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

use*_*248 16 merge r list

我有一个包含数据框的列表作为其在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)
Run Code Online (Sandbox Code Playgroud)

是否可以在不使用循环的情况下将mylist的所有元素合并在一起?

我希望这个例子的输出是:

  names age score country
1  John  21    22      US
2   Sam  22    25      SA
Run Code Online (Sandbox Code Playgroud)

此示例中的列表只有三个元素; 但是,我正在寻找一种可以处理任意数量元素的解决方案.

ags*_*udy 21

你可以使用Reduce一个班轮解决方案:

Reduce(merge,mylist)

  names age score country
1  John  21    22      US
2   Sam  22    25      SA
Run Code Online (Sandbox Code Playgroud)


ale*_*han 8

快速而肮脏的例子:

merge(merge(df1, df2),df3)
Run Code Online (Sandbox Code Playgroud)

编辑 - 这里非常相似的问题:同时合并列表中的多个data.frames

解:

merged.data.frame = Reduce(function(...) merge(..., all=F), my.list)
Run Code Online (Sandbox Code Playgroud)

免责声明 - 我从@Charles回复的所有内容都是为了制作merge(..., all=F)而不是T- 这样它就能提供您想要的输出.


Aar*_*ica 5

只是为了表明它可以用另一种方式完成......

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
Run Code Online (Sandbox Code Playgroud)

人们可以很容易地适应删除缺少值的行,或者可能只是随后删除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
Run Code Online (Sandbox Code Playgroud)