如果我有一个列表列表,并且该列表包含一组数据帧,我想将数据帧合并在一起,但不要将所有列表合并在一起。例如
list<- list(list(df1_2010,df2_2010,df3_2010), list(df1_2011,df2_2011,df3_2011), list(df1_2012,df2_2012,df3_2012))
我希望将所有2010年的数据框合并在一起,比如列id。我希望将2011年的数据框合并为一个类似的列ID,我希望将所有2012年的数据框合并为另一个类似的列ID。
我希望按年输出合并数据框列表:
list(df2010, df2011, df2012)
这是我想如何使用Reduce功能的示意图:
f<-function(b) merge(...,by="ID",all.x=T)
list<- Reduce(f, list)
但我认为这会将所有三个列表合并而不是分别合并每个列表。让我知道你的建议。
答案 0 :(得分:1)
这是一个简单的可重现的例子,我认为它映射到你的结构:
n <- 5
set.seed(n)
l <- list( list( data.frame(ID = 1:5, a = rnorm(n)),
data.frame(ID = 1:5, b = rnorm(n)),
data.frame(ID = 1:5, c = rnorm(n)),
data.frame(ID = 1:5, d = rnorm(n)) ),
list( data.frame(ID = 1:5, a = rnorm(n)),
data.frame(ID = 1:5, b = rnorm(n)),
data.frame(ID = 1:5, c = rnorm(n)),
data.frame(ID = 1:5, d = rnorm(n)) ),
list( data.frame(ID = 1:5, a = rnorm(n)),
data.frame(ID = 1:5, b = rnorm(n)),
data.frame(ID = 1:5, c = rnorm(n)),
data.frame(ID = 1:5, d = rnorm(n)) ))
您可以编写一个基于lapply
的函数,该函数在列表的每个元素上使用Reduce
:
out <-
lapply(l, function(x) Reduce(function(...) merge(..., by="ID", all.x=T), x))
您应该获得合并数据帧的列表:
str(out)
List of 3
$ :'data.frame': 5 obs. of 5 variables:
..$ ID: int [1:5] 1 2 3 4 5
..$ a : num [1:5] -0.8409 1.3844 -1.2555 0.0701 1.7114
..$ b : num [1:5] -0.603 -0.472 -0.635 -0.286 0.138
..$ c : num [1:5] 1.228 -0.802 -1.08 -0.158 -1.072
..$ d : num [1:5] -0.139 -0.597 -2.184 0.241 -0.259
$ :'data.frame': 5 obs. of 5 variables:
..$ ID: int [1:5] 1 2 3 4 5
..$ a : num [1:5] 0.901 0.942 1.468 0.707 0.819
..$ b : num [1:5] -0.293 1.419 1.499 -0.657 -0.853
..$ c : num [1:5] 0.316 1.11 2.215 1.217 1.479
..$ d : num [1:5] 0.952 -1.01 -2 -1.762 -0.143
$ :'data.frame': 5 obs. of 5 variables:
..$ ID: int [1:5] 1 2 3 4 5
..$ a : num [1:5] 1.5501 -0.8024 -0.0746 1.8957 -0.4566
..$ b : num [1:5] 0.5622 -0.887 -0.4602 -0.7243 -0.0692
..$ c : num [1:5] 1.463 0.188 1.022 -0.592 -0.112
..$ d : num [1:5] -0.925 0.7533 -0.1126 -0.0641 0.2333
答案 1 :(得分:0)
执行递归合并的另一种方法是使用库中的join_all
(plyr)
library(plyr)
out1 <- lapply(l, join_all, by="ID") #using the example dataset of @Thomas
identical(out, out1)
# [1] TRUE