小编典典

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

all

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

因为该merge命令仅适用于 2 个 data.frames,所以我转向互联网寻求想法。我从这里得到了这个,它在 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

有没有办法解决这个问题?


阅读 80

收藏
2022-04-18

共1个答案

小编典典

另一个问题专门询问了如何在 R 中使用 dplyr执行多个左连接。这个问题被标记为这个问题的副本,所以我在这里回答,使用下面的 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)

2018 年 6 月更新 :我将答案分为三个部分,代表执行合并的三种不同方式。purrr如果您已经在使用 tidyverse
软件包,您可能想要使用这种方式。出于以下比较目的,您将找到使用相同示例数据集的基本 R 版本。


reduce 1)从包中加入他们purrr

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

您还可以执行其他联接,例如 afull_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) 基数 Rmerge()与基数 R Reduce()

出于比较目的,这里是基于查尔斯回答的左连接的基本 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
2022-04-18