如何在R中合并列表的所有元素?

22
我是一名有用的助手,我可以为您翻译文本。
在R语言中,我有一个包含数据框的列表作为其元素。
例如:
df1 <- data.frame("names"=c("John","Sam","Dave"),"age"=c(21,22,25))
df2 <- data.frame("names"=c("John","Sam"),"score"=c(22,25))
df3 <- data.frame("names"=c("John","Sam","Dave"),"country"=c("US","SA","NZ"))
mylist <- list(df1,df2,df3)

是否有可能将mylist中的所有元素合并在一起而不使用循环?

对于此示例,我期望得到的输出为:

  names age score country
1  John  21    22      US
2   Sam  22    25      SA

这个例子中的列表只有三个元素;然而,我正在寻找一种可以处理任意数量元素的解决方案。
4个回答

32

您可以使用Reduce,一行解决方案:

Reduce(merge,mylist)

  names age score country
1  John  21    22      US
2   Sam  22    25      SA

8

快而简单的示例:

merge(merge(df1, df2),df3)

编辑 - 这里有一个非常类似的问题:同时合并列表中的多个数据框

解决方案:

merged.data.frame = Reduce(function(...) merge(..., all=F), my.list)

免责声明 - 我从 @Charles 的答案中改变的仅仅是将 merge(..., all=F) 替换为 T - 这样可以得到你想要的输出。

谢谢@alexwhan。我应该更具体地说明。我需要一个适用于任意数量元素列表的解决方案。我的输入列表每次可能有不同数量的元素,而不是这个示例中的三个。 - user2109248
是的,这正是我想知道的。 - alexwhan

6

只是为了展示有其他实现方法...

mymerge <- function(mylist) {
  names(mylist) <- sapply(mylist, function(x) names(x)[2])
  ns <- unique(unlist(lapply(mylist, function(x) levels(x$names))))
  as.data.frame(c(list(names=ns), lapply(mylist, function(x) 
                         {x[match(ns, x$names),2]})))
}

> mymerge(mylist)
  names age score country
1  Dave  25    NA      NZ
2  John  21    22      US
3   Sam  22    25      SA

您可以轻松地适应删除缺失值的行,或者只需使用complete.cases在之后删除。

为了证明它更快,我们将创建一个更大的数据集; 包含100个变量和25个名称。

set.seed(5)
vs <- paste0("V", 1:100)
mylist <- lapply(vs, function(v) {
  x <- data.frame(names=LETTERS[1:25], round(runif(25, 0,100)))
  names(x)[2] <- v
  x
})

> microbenchmark(Reduce(merge, mylist), myf(mylist))
Unit: milliseconds
                   expr       min        lq    median        uq       max
1           myf(mylist)  12.81371  13.19746  13.36571  14.40093  33.90468
2 Reduce(merge, mylist) 199.23714 206.28608 207.30247 208.44939 226.05980

1
嗯,我很少被踩。并不是说我从来没有做错过什么,但是留下一条评论会更好。我认为这很棒,当数据变得更大时,它将比Reduce更快,正如编辑中所示。 - Aaron left Stack Overflow
+1 分钟完成基准测试!Reduce 真的很慢! - agstudy
当使用data.frame()函数时,似乎不再能够在不指定stringsAsFactors = T的情况下使用此解决方案。 - Will T-E
嗨@WillT-E,请继续进行必要的编辑。谢谢! - Aaron left Stack Overflow

0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接