如何矢量化从列索引向量扩展压缩稀疏矩阵?

时间:2016-09-15 03:22:17

标签: r vector vectorization sparse-matrix indices

我想从矢量构建一个矩阵,如下所示:如果y的第一个元素是5,我想制作矩阵1的第一行和第五列。该行中的其他元素为0。

y=round(runif(30)*9)+1
y_m=matrix(rep(0,length(y)*10),ncol=10)
for (i in 1:length(y)){
  y_m[i,y[i]]=1;
}

有没有办法避免for循环?我试图做y_m[,y]=1,但显然它不起作用。

3 个答案:

答案 0 :(得分:4)

是:使用双列索引矩阵。来自?"["

  

通过'['单个参数'i'索引数组时可以是a             矩阵的列数与“x”的维数一样多;             结果是一个元素对应的向量             'i'每行中的索引集。

设定:

set.seed(101)
y <- round(runif(30)*9)+1

你的方式(我简化了矩阵结构):

y_m <- matrix(0,ncol=10,nrow=length(y))
for (i in 1:length(y)){
  y_m[i,y[i]] <- 1
}

通过矩阵索引:

y_m2 <- matrix(0,ncol=10,nrow=length(y))
y_m2[cbind(1:length(y),y)] <- 1

检查:

all.equal(y_m,y_m2)  ## TRUE

答案 1 :(得分:3)

您可以使用:

y_m[cbind(1:length(y), y)] <- 1

由于你有一个稀疏矩阵,你可能需要:

sparse_y_m <- Matrix::sparseMatrix(i = 1:length(y), j = y, x = 1)

如果您需要完整矩阵,请使用

y_m <- as.matrix(sparse_y_m)

答案 2 :(得分:2)

您可以使用xtabs仅从y制作矩阵,通过行号索引传播1s的向量,即seq_along(y)然后y本身:

xtabs(rep(1, length(y)) ~ seq_along(y) + y)
##             y
## seq_along(y) 1 2 3 4 5 6 7 8 9 10
##           1  0 0 0 1 0 0 0 0 0  0
##           2  0 1 0 0 0 0 0 0 0  0
##           3  1 0 0 0 0 0 0 0 0  0
##           4  0 0 0 0 0 0 1 0 0  0
##           5  0 0 0 1 0 0 0 0 0  0
##           6  0 0 0 1 0 0 0 0 0  0
##           ...

或使其成为稀疏矩阵:

xtabs(rep(1, length(y)) ~ seq_along(y) + y, sparse = TRUE)
## 30 x 10 sparse Matrix of class "dgCMatrix"
##                       
## 1  . . . 1 . . . . . .
## 2  . 1 . . . . . . . .
## 3  1 . . . . . . . . .
## 4  . . . . . . 1 . . .
## 5  . . . 1 . . . . . .
## 6  . . . 1 . . . . . .
## ...

或使用data.frame进行设置以获得更好的标签:

xtabs(i ~ row + y, data.frame(y, i = 1, row = seq_along(y)))
##     y
## row  1 2 3 4 5 6 7 8 9 10
##   1  0 0 0 1 0 0 0 0 0  0
##   2  0 1 0 0 0 0 0 0 0  0
##   3  1 0 0 0 0 0 0 0 0  0
##   4  0 0 0 0 0 0 1 0 0  0
##   5  0 0 0 1 0 0 0 0 0  0
##   6  0 0 0 1 0 0 0 0 0  0
##   ...