给定一个 0/1 矩阵,我试图生成每行中 1 的索引位置列表。我可以使用 for
循环来做到这一点:
B <- matrix(sample(c(0,1),100,replace=T),nrow=10,ncol=10)
ones <- list()
for (row in 1:nrow(B)) {ones[[row]] <- (which(B[row,]==1))}
生成的对象ones
就是我想要的。我认为使用 apply()
会稍微快一些,但我在将循环转换为 apply 时遇到了麻烦。这不会产生相同的结果:
alt <- apply(B, 1, function(x) which(B[x,]==1))
如果有任何关于如何纠正apply
的建议,我将不胜感激,以便它产生与循环方法相同的结果。谢谢!
更新 -
我接受了@TarJae的回答,因为它有效,只需要一行,而且速度很快。 @Ronak 的方法也有效,但比其他选项慢。以下是三种方法的比较:
library(rbenchmark)
B <- matrix(sample(c(0,1),1000000,replace=T),nrow=1000,ncol=1000)
benchmark(
"loop" = {
ones_loop <- list()
for (row in 1:nrow(B)) {ones_loop[[row]] <- (which(B[row,]==1))}
},
"apply" = {
ones_apply <- apply(B==1,1, which)
},
"split" = {
ones_split <- which(B == 1, arr.ind = TRUE)
ones_split <- split(ones_split[, 2], ones_split[, 1])
},
replications = 500
)
test replications elapsed relative user.self sys.self user.child sys.child
2 apply 500 17.211 1.000 15.068 2.111 0 0
1 loop 500 19.466 1.131 16.778 2.349 0 0
3 split 500 40.291 2.341 33.757 6.150 0 0
最佳答案
您可以这样使用apply
:给出与循环相同的结果:
apply(B==1,1, which)
> apply(B==1,1, which)
[[1]]
[1] 4 6 7 8 10
[[2]]
[1] 1 4 5 10
[[3]]
[1] 1 2 3 4 5 7 9
[[4]]
[1] 2 3 4 5 9
[[5]]
[1] 2 4 8 10
[[6]]
[1] 4 5 7 8
[[7]]
[1] 1 2 5 8 9 10
[[8]]
[1] 1 3 4 7 8 9 10
[[9]]
[1] 1 2 4 5 6 7 10
[[10]]
[1] 1 3 4 6 7 10
关于r - 使用 R apply 索引矩阵中 1 的位置,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68873081/