首页 > 解决方案 > 比较不同列表中嵌入数据框的特定列

问题描述

假设我有两个包含以下嵌入数据框的列表:

# Data frames to intersect
US <- data.frame("Group" = c(1,2,3), "Age" = c(21,20,17), "Name" = c("John","Dora","Helen"))
CA <- data.frame("Group" = c(2,3,4), "Age" = c(21,20,19), "Name" = c("John","Dora","Dan"))
JP <- data.frame("Group" = c(4,5,6), "Age" = c(16,15,14), "Name" = c("Mac","Hector","Jack"))

# Lists to compare----
list1<-list(US,CA,JP)
names(list1)<-c("US","CA","JP")

# List 2 can serve as a "reference list," a duplicate of the first.
list2<-list(US,CA,JP)
names(list2)<-c("US","CA","JP")

我有第二个清单,作为第一个清单的“参考清单”。它是副本,仅用于在某些操作中用作参考,例如 for 循环。我想要做的是intersect仅来自第一列(例如Group)的标量/值,并将相交的输出存储在单独的数据帧或矩阵中。我不想与具有相同名称的数据框组相交(即 List 1 US 组不应与 List 2 US 组相交)。

理想情况下,将创建一个 DF 的最终列表,其中包含所有可能的相交 DF 组合、它们的名称和最终输出的结果,其效果如下:

print(comb_list)
$US_CA
  Group
1     2    
2     3

$US_JP
data frame with 0 columns and 0 rows

$CA_JP
  Group
1     4

是否可以将其创建为 for 循环?

标签: rlistdataframeloopsintersection

解决方案


当然,使用嵌套的 for 循环看起来是可行的。无需复制初始列表。循环可以遍历同一个列表。我建议使用 dplyr,因为它是方便的过滤器和选择功能

require(dplyr)
comb_list <- list()

for (i in 1:length(list1)) {
  for (j in 1:length(list1)) {
    # don't intersect country with itself
    if (names(list1)[i] != names(list1)[j]) {

      value <- filter(list1[[i]], Group %in% list1[[j]]$Group)
      value <- select(value, Group)
      
      name <- paste0(names(list1)[i], "_", names(list1[j]))
      name_alt <- paste0(names(list1)[j], "_", names(list1[i]))

      #don't store equivalent country intersections i.e. US_CA and CA_US
      if (!name %in% names(comb_list) & !name_alt %in% names(comb_list)) {
        comb_list[[name]] <- value
      }
    }
  }
}

print(comb_list)
$US_CA
  Group
1     2
2     3

$US_JP
[1] Group
<0 rows> (or 0-length row.names)

$CA_JP
  Group
1     4

推荐阅读