我想从矢量构建一个矩阵,如下所示:如果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
,但显然它不起作用。
答案 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
## ...