如何在矩阵的每n列插入一列而不使用apply或looping

时间:2015-09-26 03:46:19

标签: r matrix vectorization

假设我有一个矩阵

M = diag(6)

我要插入

d = rep(5,6)

每隔3列,输出为

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

输出:

     [,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

1 个答案:

答案 0 :(得分:3)

我们通过更多列创建另一个matrix 5(' m1'),创建列索引(使用setdiffseq)来替换值在' 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

编辑:

我猜这不是创建另一个巨大的matrix,而是cbind其他列可能对内存有效,然后order

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

基准

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