从长度不等的列表中加入数据框

时间:2019-11-19 12:28:27

标签: r tidyverse

我有两个要合并的数据帧列表,我尝试了以下操作:

A <- data.frame(ID = c(1,2,3),
                var1 = c(3,4,5),
                var2 = c(6,3,2))
B <- data.frame(ID = c(1,2,3),
                var1 = c(4,4,5),
                var2 = c(6,7,3))
C <- data.frame(ID = c(1,2,3),
                var1 = c(1,4,8),
                var2 = c(9,2,3))

list1 <- list(A = A, B = B, C = C)
list2 <- list(A = A, B = B)

combined <- map2(list1, list2, full_join, by = 'ID')

这将返回一个错误,即两个列表的长度不同。我想到的唯一另一种方法是在第二个列表中添加一个空白数据框,使它们的长度相同。

是否可以合并两个列表,以便得到一个列表,其中A1已与A2连接在一起,B1已与B2连接在一起,而C1保持原样?

编辑:突出显示我没有命名列表中的元素,我现在已经命名了

2 个答案:

答案 0 :(得分:3)

如果我们已命名列表,则可以:

list1 <- list(A = A, B = B, C = C)
list2 <- list(A = A, B = B)

x12 <- intersect(names(list1), names(list2))
x1 <- setdiff(names(list1), names(list2))
x2 <- setdiff(names(list2), names(list1))

combined <- c(
  map2(list1[ x12 ], list2[ x12 ], full_join, by = 'ID'),
  list1[ x1 ],
  list2[ x2 ])

答案 1 :(得分:1)

如果您想继续处理职位,还可以传递占位符并在合并逻辑中处理它们。像这样:

skip <- tibble(ID = integer(0))

list1 <- list(A, B, C)
list2 <- list(A, B, skip)
list3 <- list(A, skip, C)

combined  <- map2(list1, list2, full_join, by = 'ID')
combined2 <- map2(list1, list3, full_join, by = 'ID')

请注意,list2list3如果不使用占位符,将看起来完全一样!

更笼统地说:


list1 <- list(A, B, C)
list2 <- list(A, B, NULL)
list3 <- list(A, NULL, C)

combine <- function(list1, list2) {
   purrr::map2(list1, list2, function(df1, df2) {
      if (is.null(df1)) return(df2)
      if (is.null(df2)) return(df1)
      full_join(df1, df2, by = 'ID')
   })
}

combined  <- combine(list1, list2)
combined2 <- combine(list1, list3)