r - How to insert a column every n columns of a matrix without using apply or looping -


suppose have matrix

m = diag(6) 

and want insert

d = rep(5,6) 

every 3rd column output is

m      [,1] [,2] [,3] [,4] [,5] [,6] [1,]    1    0    0    0    0    0 [2,]    0    1    0    0    0    0 [3,]    0    0    1    0    0    0 [4,]    0    0    0    1    0    0 [5,]    0    0    0    0    1    0 [6,]    0    0    0    0    0    1 > d [1] 5 5 5 5 5 5 

output:

     [,1] [,2] [,3] [,4]  [,5]   [,6]  [,7]   [,8] [1,]    1    0    0    5    0       0    0      5 [2,]    0    1    0    5    0       0    0      5 [3,]    0    0    1    5    0       0    0      5 [4,]    0    0    0    5    1       0    0      5 [5,]    0    0    0    5    0       1    0      5 [6,]    0    0    0    5    0       0    1      5 

we create matrix of 5 ('m1') more number of columns, create column index (using setdiff , seq) replace values in 'm1' 'm'

n <- 3 m1 <- matrix(5, ncol=ncol(m)+ncol(m)/n, nrow=nrow(m)) m1[,setdiff(1:ncol(m1),seq(4, ncol(m1), by=4))] <- m m1 #     [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] #[1,]    1    0    0    5    0    0    0    5 #[2,]    0    1    0    5    0    0    0    5 #[3,]    0    0    1    5    0    0    0    5 #[4,]    0    0    0    5    1    0    0    5 #[5,]    0    0    0    5    0    1    0    5 #[6,]    0    0    0    5    0    0    1    5 

edit:

i guess instead of creating huge matrix, might memory efficient cbind additional columns , order columns

n1 <- ncol(m)/n m1 <- matrix(5, nrow=nrow(m), ncol=n1) m2 <- cbind(m, m1)  n2 <- seq(4, ncol(m2), by=4) m3 <- m2[,order(c(setdiff(seq_len(ncol(m2)), n2), n2))] m3 #     [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] #[1,]    1    0    0    5    0    0    0    5 #[2,]    0    1    0    5    0    0    0    5 #[3,]    0    0    1    5    0    0    0    5 #[4,]    0    0    0    5    1    0    0    5 #[5,]    0    0    0    5    0    1    0    5 #[6,]    0    0    0    5    0    0    1    5 

benchmarks

m <- diag(5000) n <- 3 system.time({ n1 <- ncol(m)/n m1 <- matrix(5, nrow=nrow(m), ncol=n1) m2 <- cbind(m, m1)  n2 <- seq(n+1, ncol(m2), by=n+1) m3 <- m2[,order(c(setdiff(seq_len(ncol(m2)), n2), n2))] }) #  user  system elapsed  #  0.699   0.068   0.769   n <- 3 system.time({ m1 <- matrix(5, ncol=ncol(m)+ncol(m)/n, nrow=nrow(m)) m1[,setdiff(1:ncol(m1),seq(n+1, ncol(m1), by=n+1))] <- m }) #user  system elapsed  #  0.722   0.061   0.785   identical(m1, m3) #[1] true 

Comments