【问题标题】:How to merge all elements of list in R? [duplicate]如何合并R中列表的所有元素? [复制]
【发布时间】:2013-02-11 07:12:57
【问题描述】:

我有一个列表,其中包含数据框作为其在 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

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

【问题讨论】:

    标签: r list merge


    【解决方案1】:

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

    Reduce(merge,mylist)
    
      names age score country
    1  John  21    22      US
    2   Sam  22    25      SA
    

    【讨论】:

      【解决方案2】:

      快速而肮脏的例子:

      merge(merge(df1, df2),df3)
      

      编辑 - 非常相似的问题在这里:Simultaneously merge multiple data.frames in a list

      解决方案:

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

      免责声明 - 我从 @Charles 的答案中改变的只是 merge(..., all=F) 而不是 T - 这样它就可以提供您想要的输出。

      【讨论】:

      • 谢谢@alexwhan。我应该更具体。我需要一个包含任意数量元素的列表的解决方案。我的输入列表每次可能有不同数量的元素,而不是本例中的三个。
      • 是的,这就是我想知道的
      【解决方案3】:

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

      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
      

      【讨论】:

      • 好吧,我很少被否决。并不是说我有时不应该得到它,但评论会很好。我认为这很漂亮,当数据变大时会比Reduce 更快,如编辑所示。
      • 基准+1!减少真的很慢!
      • 在使用 data.frame() 函数时,如果不指定 stringsAsFactors = T,此解决方案似乎不再有效
      • 嗨@WillT-E,请继续进行必要的编辑。谢谢!
      【解决方案4】:

      你试过这个功能吗?

      http://rss.acs.unt.edu/Rdoc/library/gtools/html/smartbind.html

      library(gtools)
      df1 <- data.frame(list(A=1:10), B=LETTERS[1:10], C=rnorm(10) )
      df2 <- data.frame(A=11:20, D=rnorm(10), E=letters[1:10] )
      df3 <- df1
      
      out <- smartbind( mylist <- list(df1,df2,df3))
      

      【讨论】:

        猜你喜欢
        • 2013-06-01
        • 2016-02-01
        • 1970-01-01
        • 2021-05-12
        • 2015-01-04
        • 2021-12-26
        • 2016-08-14
        • 2014-06-08
        • 1970-01-01
        相关资源
        最近更新 更多