我试图评估列表中一系列长度为10的非冗余元素对之间的交集(例如" abc"),对于每个元素,它包含两个长度为20的整数向量,并为具有超过一定数量(例如2)的交叉点生成对索引的向量,如下所示:
set.seed(42)
abc <- replicate(10, list(sample(1:100, 20), sample(1:100, 20)), simplify=F)
edges <- c()
for (i in 1:(length(abc)-1)) {
for (j in (i+1):length(abc)) {
if (length(intersect(abc[[i]][[1]], abc[[j]][[1]])) >= 2 & length(intersect(abc[[i]][[2]], abc[[j]][[2]])) >= 2) {
edges <- c(edges, c(i,j))
}
}
}
我只是想知道是否有其他方法可以产生相同的结果,但是效率更高更快?使用具有合理大小的列表的循环似乎没问题,但是当涉及到更大的列表时,它需要比预期更多的时间。我试图使用&#39; lapply&#39;或其他类似的功能,但使用那些&#39; lapply&#39;对于单循环来说,类型函数似乎很简单,但对于具有不同循环迭代次数的双循环,我很难找到一个好的解决方案。提前谢谢!
答案 0 :(得分:0)
您可以使用combs
生成可以迭代的索引:
set.seed(47)
abc <- replicate(10, list(sample(1:100, 20), sample(1:100, 20)), simplify=F)
combs <- combn(length(abc), 2)
i <- apply(combs, 2, function(x){
length(intersect(abc[[x[1]]][[1]], abc[[x[2]]][[1]])) >= 2 &
length(intersect(abc[[x[1]]][[2]], abc[[x[2]]][[2]])) >= 2
})
combs[,i]
#> [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10] [,11] [,12] [,13]
#> [1,] 1 1 1 1 1 1 1 1 1 2 2 2 2
#> [2,] 2 3 4 5 6 7 8 9 10 3 4 5 6
#> [,14] [,15] [,16] [,17] [,18] [,19] [,20] [,21] [,22] [,23] [,24]
#> [1,] 2 2 2 3 3 3 3 3 4 4 4
#> [2,] 7 8 10 4 6 8 9 10 5 6 7
#> [,25] [,26] [,27] [,28] [,29] [,30] [,31] [,32] [,33] [,34] [,35]
#> [1,] 4 4 4 5 5 5 5 5 6 6 6
#> [2,] 8 9 10 6 7 8 9 10 7 8 9
#> [,36] [,37] [,38] [,39] [,40] [,41]
#> [1,] 6 7 7 7 8 9
#> [2,] 10 8 9 10 10 10
但请注意,因为组合快速变大,而10个元素(choose(10, 2)
= 45种组合)的速度很快,对于10,000个元素的不可想象的列表,检查choose(10000, 2)
= 49,995,000与两个子元素的组合每个都会占用更多的内存和时间。