如何按名称组合两个数据帧列表

时间:2014-08-01 16:36:57

标签: r merge dataframe

我有两个数据框列表,例如:

names1 <- c("1", "2")
mydf1 <- data.frame(V1=c(1:2), V2=rep("A",2)) 
mydf2 <- data.frame(V1=c(1:3), V2=rep("B",3))
list1 <- list(mydf1,mydf2)

names2 <- c("1","1","2")
mydf4 <- data.frame(V1=c(1:3), V2=rep("BB",3)) 
mydf5 <- data.frame(V1=c(1:3), V2=rep("CC",3)) 
mydf6 <- data.frame(V1=c(1:3), V2=rep("DD",3)) 
list2 <- list(mydf4,mydf5,mydf6)

names(list1) <- names1
names(list2) <- names2

我希望通过相同的名称组合成列表。我想要这样的东西:

$`1`
  V1 V2
1  1  A
2  2  A
3  1 BB
4  2 BB
5  3 BB

$`1`
  V1 V2
1  1  A
2  2  A
3  1 CC
4  2 CC
5  3 CC

$'2'
  V1 V2
1  1  B
2  2  B
3  3  B
4  1 DD
5  2 DD
6  3 DD

我试过

mapply(rbind, list1, list2, SIMPLIFY=FALSE)

但结果很混乱

任何想法?谢谢!

2 个答案:

答案 0 :(得分:4)

当在子集中重复名称时,相应的变量也会在结果中重复。使用此事实,我们可以使用match(),然后使用Map()

(m <- match(names(list2), names(list1), nomatch = 0L))
# [1] 1 1 2
Map(rbind, list1[m], list2)

返回所需的列表

List of 3
 $ 1:'data.frame':  5 obs. of  2 variables:
  ..$ V1: int [1:5] 1 2 1 2 3
  ..$ V2: Factor w/ 2 levels "A","BB": 1 1 2 2 2
 $ 1:'data.frame':  5 obs. of  2 variables:
  ..$ V1: int [1:5] 1 2 1 2 3
  ..$ V2: Factor w/ 2 levels "A","CC": 1 1 2 2 2
 $ 2:'data.frame':  6 obs. of  2 variables:
  ..$ V1: int [1:6] 1 2 3 1 2 3
  ..$ V2: Factor w/ 2 levels "B","DD": 1 1 1 2 2 2

答案 1 :(得分:1)

假设“list1”没有重复的名称,但“list2”没有(如示例数据中所示),您可以创建一个如下所示的辅助函数来执行任务:

stackMe <- function(x) {
  a <- eval.parent(quote(names(X)))[substitute(x)[[3]]]
  rbind(list1[[a]], x)
} 

第一行(从this answer借来)抓取正在处理的列表项的名称。我们可以在第二行使用它来访问“list1”中的相关值。

以下是此示例数据的结果:

lapply(list2, stackMe)
# $`1`
#   V1 V2
# 1  1  A
# 2  2  A
# 3  1 BB
# 4  2 BB
# 5  3 BB
# 
# $`1`
#   V1 V2
# 1  1  A
# 2  2  A
# 3  1 CC
# 4  2 CC
# 5  3 CC
# 
# $`2`
#   V1 V2
# 1  1  B
# 2  2  B
# 3  3  B
# 4  1 DD
# 5  2 DD
# 6  3 DD