我有一个包含数据框的列表作为其在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)
快速而肮脏的例子:
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- 这样它就能提供您想要的输出.
只是为了表明它可以用另一种方式完成......
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)