使用Reduce函数递归合并

时间:2014-07-28 20:07:22

标签: r

如果我有一个列表列表,并且该列表包含一组数据帧,我想将数据帧合并在一起,但不要将所有列表合并在一起。例如

 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)

但我认为这会将所有三个列表合并而不是分别合并每个列表。让我知道你的建议。

2 个答案:

答案 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