2017-04-20 39 views
0

我試圖評估長度爲10(例如「abc」)的列表中的一系列非冗餘元素對之間的交集,對於每個元素,包含具有長度爲20的兩個整矢量,並生成用於所述一對索引爲具有交叉點的矢量超過一定次數(例如2),如下所示:替代使用R編程中列表中不同長度的成對迭代的雙循環

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)) 
    } 
    } 
} 

我只是想知道如果還有其他方法可以產生相同的結果,但效率更高,速度更快?使用合理大小的列表循環看起來沒問題,但是當涉及到一個更大的列表時,它需要比預期更多的時間。我試圖使用'lapply'或其他類似的函數,但是對於單個循環使用那些'lapply'類型的函數似乎很簡單,但對於具有不同數量的循環迭代的雙重循環,我很難想出一個好的解決方案。先謝謝你!

+0

你現實需要什麼?重要的是你需要相交嗎?整數矢量的值是否爲1..100?你的名單的大小是多少? – user31264

回答

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個組合,其中包含兩個子元素,每個元素需要更多的內存和時間。