2016-09-15 92 views
3

我想建立从载体如下的矩阵:如果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,但显然它不工作。

+2

我认为你的意思是*“从列索引向量展开压缩的稀疏矩阵”* – smci

+1

不同的方法:'xtabs(rep(1,length(y))〜seq_along(y)+ y)' – alistaire

回答

4

是:使用两列索引矩阵。从?"["

当由“[”的单个参数的索引阵列“I”可以是 矩阵与尽可能多列作为有“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 
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

您可以使用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 
## ... 
+0

我试过了, 'data.matrix''model.matrix',非常接近...谢谢! – hxd1011