2017-07-30 107 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的地理距离),并且我没有看到我可以如何在网格中执行此操作。 –