2017-07-30 99 views
1

我想將df中的每一行與同一df中的每一行進行比較(並計算一些函數)。我設法編寫了一個foreach循環,但它只將每行與最後一行進行比較。R foreach循環比較每一行到每一行

這裏是我做的事,到目前爲止最小的我們:

# create toy df 
ID <- c(345, 476, 234, 987, 123) # assign random id 
Language <- c("aa", "bb", "cc", "dd", "ee") # names of languages 
Latitude <- c(-17, -25, 44, -8, 29) 
Longitude <- c(130, 29, -122, 120, -110) 
sample <- data.frame(ID, Language, Latitude, Longitude) 


sample 
    ID Language Latitude Longitude 
1 345  aa  -17  130 
2 476  bb  -25  29 
3 234  cc  44  -122 
4 987  dd  -8  120 
5 123  ee  29  -110 


# foreach loop that should pair every language with every other 
sample.rows <- nrow(sample) 

loop <- foreach(i=1:(sample.rows-1),.combine=rbind) %do% { 
    empty.pairs <- c() 
    for(j in (i+1):sample.rows){ 
    pairs <- rbind(empty.pairs, c(i, j)) 
    } 
    data.frame(Lang1 = sample$Language[pairs[,1]], 
       Lang2 = sample$Language[pairs[,2]], 
       i= pairs[,1], 
       j= pairs[,2]) 
    } 

其輸出以下:

loop 
Lang1 Lang2 i j 
1 aa ee 1 5 
2 bb ee 2 5 
3 cc ee 3 5 
4 dd ee 4 5 

即僅環前四行到最後一行進行比較,但我希望它將所有行與所有其他行進行比較,例如語言「aa」不僅應該與「ee」進行比較,還應該與「bb」,「cc」和「dd」進行比較。 任何提示讚賞!

+0

您正在重置每個循環中的empty.pairs。 – Dave2e

+0

如果您知道要創建的對象的大小,請預先分配它並填充它,而不是增加空對象。 –

+0

@ Dave2e:好的,我該如何避免這樣做? –

回答

0

我想你想要的是一個所有語言組合的網格。您可以使用expand.grid

grid <- cbind(
    expand.grid(sample$Language, sample$Language), 
    expand.grid(seq_len(sample.rows), seq_len(sample.rows)) 
) 
names(grid) <- c("Lang1", "Lang2", "i", "j") 
grid <- grid[grid[["j"]] > grid[["i"]], ] 

PS:如果您想要計算距離,使用矩陣會比數據幀更好。

+0

我接受它是因爲它回答了我所問的問題 - 感謝您寫出來!儘管如此,我仍然堅持循環,因爲我需要應用基於原始df的幾個函數(例如兩個lang的地理距離),並且我沒有看到我可以如何在網格中執行此操作。 –