r - 同时合并列表中的多个 data.frames

标签 r list merge dataframe r-faq

我有一个要合并的许多 data.frame 的列表。这里的问题是每个 data.frame 的行数和列数都不同,但它们都共享关键变量(我称之为 "var1""var2" 在下面的代码中)。如果 data.frames 在列方面相同,我只需 rbind,为此 plyr 的 rbind.fill可以完成这项工作,但这些数据的情况并非如此。

由于 merge 命令仅适用于 2 个 data.frame,因此我向互联网寻求想法。我从 here 得到了这个,它在 R 2.7.2 中完美运行,这就是我当时的版本:

merge.rec <- function(.list, ...){
    if(length(.list)==1) return(.list[[1]])
    Recall(c(list(merge(.list[[1]], .list[[2]], ...)), .list[-(1:2)]), ...)
}

我会这样调用该函数:

df <- merge.rec(my.list, by.x = c("var1", "var2"), 
                by.y = c("var1", "var2"), all = T, suffixes=c("", ""))

但是在 2.7.2 之后的任何 R 版本(包括 2.11 和 2.12)中,此代码都会失败并出现以下错误:

Error in match.names(clabs, names(xi)) : 
  names do not match previous names

(顺便说一句,我看到其他对此错误的引用 elsewhere 但没有解决方案)。

有什么办法可以解决这个问题吗?

最佳答案

另一个专门提出的问题how to perform multiple left joins using dplyr in R 。该问题被标记为与此问题重复,因此我在这里使用下面的 3 个示例数据框进行回答:

x <- data.frame(i = c("a","b","c"), j = 1:3, stringsAsFactors=FALSE)
y <- data.frame(i = c("b","c","d"), k = 4:6, stringsAsFactors=FALSE)
z <- data.frame(i = c("c","d","a"), l = 7:9, stringsAsFactors=FALSE)

答案分为三个部分,代表执行合并的三种不同方式。如果您已经在使用 tidyverse 软件包,您可能需要使用 purrr 方式。为了进行下面的比较,您将找到使用相同示例数据集的基本 R 版本。

<小时/>

1) 使用 purrr 包中的 reduce 将它们加入:

purrr 包提供了一个 reduce 函数,它具有简洁的语法:

library(tidyverse)
list(x, y, z) %>% reduce(left_join, by = "i")
#  A tibble: 3 x 4
#  i       j     k     l
#  <chr> <int> <int> <int>
# 1 a      1    NA     9
# 2 b      2     4    NA
# 3 c      3     5     7

您还可以执行其他联接,例如 full_joininner_join:

list(x, y, z) %>% reduce(full_join, by = "i")
# A tibble: 4 x 4
# i       j     k     l
# <chr> <int> <int> <int>
# 1 a     1     NA     9
# 2 b     2     4      NA
# 3 c     3     5      7
# 4 d     NA    6      8

list(x, y, z) %>% reduce(inner_join, by = "i")
# A tibble: 1 x 4
# i       j     k     l
# <chr> <int> <int> <int>
# 1 c     3     5     7
<小时/>

2) dplyr::left_join() 与基础 R Reduce():

list(x,y,z) %>%
    Reduce(function(dtf1,dtf2) left_join(dtf1,dtf2,by="i"), .)

#   i j  k  l
# 1 a 1 NA  9
# 2 b 2  4 NA
# 3 c 3  5  7
<小时/>

3) 基础 R merge() 与基础 R Reduce():

出于比较目的,这里是基于 Charles 答案的左连接的基本 R 版本。

 Reduce(function(dtf1, dtf2) merge(dtf1, dtf2, by = "i", all.x = TRUE),
        list(x,y,z))
#   i j  k  l
# 1 a 1 NA  9
# 2 b 2  4 NA
# 3 c 3  5  7

关于r - 同时合并列表中的多个 data.frames,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8091303/

相关文章:

r - 积分函数中多个参数对应的多个数组的所有可能组合

python - 许多文本文件中的大量数据 - 如何处理?

r - 如何在 R v3.1.2 上安装多核软件包?

r - 从列表列表制作数据框,但每个元素都是一列

javascript - 如何在javascript中动态地将带有数组的深层JS对象减少为没有数组的JS对象?

python - Pandas :根据多级首次出现合并数据框

r - R markdown 中的 reshape 问题

Python 字符串操作。第五位加一个角色

java - 对随机传入数据进行排序的内存和时间高效方法

git - 在多次错误提交后 merge 分支