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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/15078896/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-11 01:58:09  来源:igfitidea点击:

How to merge all elements of list in R?

rlistmerge

提问by user2109248

I have a list containing data frames as its elements in R.

我有一个列表,其中包含数据框作为 R 中的元素。

Example:

例子:

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)

Is it possible to merge all the elements of mylist together without using a loop?

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

My desired output for this example is:

这个例子我想要的输出是:

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

The list in this example has only three elements; however, I am looking for a solution that can handle an arbitrary number of elements.

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

回答by agstudy

You can use Reduce, one liner solution:

您可以使用Reduce一种衬垫解决方案:

Reduce(merge,mylist)

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

回答by alexwhan

Quick and dirty example:

快速而肮脏的例子:

merge(merge(df1, df2),df3)


EDIT- Very similar question here:Simultaneously merge multiple data.frames in a list

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

solution:

解决方案:

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

Disclaimer - All I changed from @Charles answer was to make merge(..., all=F)rather than T- this way it gives your desired output.

免责声明 - 我从 @Charles 答案中更改的所有内容都是 makemerge(..., all=F)而不是T- 这样它就可以提供您想要的输出。

回答by Aaron left Stack Overflow

Just to show it could be done another way...

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

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

One could easily adapt to remove rows with missing values, or perhaps just remove afterwards with complete.cases.

人们可以很容易地适应删除缺少值的行,或者可能只是在之后使用complete.cases.

To show that it's faster, we'll make up a bigger data set; 100 variables and 25 names.

为了证明它更快,我们将组成一个更大的数据集;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

回答by alap

Have you tried this function?

你试过这个功能吗?

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

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))