如何合并不等长的数据框列表?

How to merge dataframe lists of unequal length?

这个问题类似于

我有一个 shiny 脚本,我在其中使用 fileImport 来允许用户导入可变数量的数据文件。然后将每个数据文件拆分为一个数据帧列表,并将这些作为列表导入。所以我有一个数据帧列表的列表。

输入数据文件有两种可能的格式,一种可能是 129 数据帧长,另一种可能是 67 - 其中 67 实际上是 129 的子集(因此所有 67 都出现在 129 中,但不是所有 129出现在 67)。然后我尝试按名称 rbind 数据帧。

一个可重现的例子:

# Some data
df.l1 <- list(df1 = data.frame(A = letters[1:10],
                               B = rnorm(10, 5, 1)),
              df2 = data.frame(A = letters[11:20],
                               B = rnorm(10, 10, 2)))

df.l2 <- list(df1 = data.frame(A = letters[1:10],
                               B = rnorm(10, 5, 1)),
              df2 = data.frame(A = letters[11:20],
                               B = rnorm(10, 10, 2)))

df.l3 <- list(df1 = data.frame(A = letters[1:10],
                               B = rnorm(10, 5, 1)),
              df2 = data.frame(A = letters[11:20],
                               B = rnorm(10, 10, 2)),
              df3 = data.frame(A = LETTERS[1:10],
                               B = rnorm(10, 15, 2)))

这适用于绑定长度相等的列表(例如 df.l1 和 df.l2)

df.two <- list(df.l1, df.l2)
list.merged <- do.call(function(...) Map(rbind, ...), df.two)

但在绑定具有可变长度的数据帧列表时失败。

df.three <- list(df.l1, df.l2, df.l3)
list.merged <- do.call(function(...) Map(rbind, ...), df.three)

报错:

Warning messages:
1: In mapply(FUN = f, ..., SIMPLIFY = FALSE) :
  longer argument not a multiple of length of shorter
2: In mapply(FUN = f, ..., SIMPLIFY = FALSE) :
  longer argument not a multiple of length of shorter

正如我上面所说,已经提出了类似的问题,但鉴于我尝试合并的列表数量可变,这种情况是独一无二的。非常感谢您的帮助!

为了稳健地处理这个问题,我会使用 dplyr::bind_rowsdata.table::rbindlist。首先绑定每个列表,然后在上层绑定:

tidyverse版本:

library(dplyr) 

bind_rows(lapply(df.three, bind_rows))

data.table版本:


library(data.table)

rbindlist(lapply(df.three, rbindlist))

这不仅可以处理您意想不到的奇怪极端情况,而且比 do.call.

快得多

根据评论进行编辑

试试这个:

library(purrr)
library(dplyr)
df_names <- unique(unlist(sapply(df.three, names)))
result <- list()
for (n in df_names) {
  result[[n]] <- map(df.three, n)
}
map(result, dplyr::bind_rows)