我有一个我要合并的许多data.frames的列表 . 这里的问题是每个data.frame在行数和列数方面都有所不同,但它们都共享关键变量(我在下面的代码中称之为 "var1"
和 "var2"
) . 如果data.frames在列方面是相同的,我只能 rbind
,plyr的rbind.fill可以完成这项工作,但这些数据并非如此 .
因为 merge
命令仅适用于2个data.frames,所以我转向Internet寻求创意 . 我从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没有解决方案) .
有什么方法可以解决这个问题吗?
6 回答
另一个问题具体问了how to perform multiple left joins using dplyr in R . 这个问题被标记为这个问题的副本,所以我在这里回答,使用下面的3个示例数据框:
Update June 2018 :我将答案分为三个部分,分别代表三种不同的方式来执行合并 . 如果您已经在使用 tidyverse 包,则可能需要使用
purrr
方式 . 为了进行比较,您将找到使用相同样本数据集的基本R版本 .使用purrr包中的reduce加入它们
purrr
包提供了reduce
函数,该函数具有简洁的语法:您还可以执行其他连接,例如
full_join
或inner_join
:dplyr :: left_join()with base R Reduce()
Base R merge()与base R Reduce()
为了进行比较,这里是左连接的基本R版本
减少使这相当容易:
这是使用一些模拟数据的完整示例:
这是一个使用these data复制
my.list
的示例:注意:看起来这可能是
merge
中的一个错误 . 问题是没有检查添加后缀(处理重叠的非匹配名称)实际上使它们唯一 . 在某一点上,它使用[.data.frame
,这会使make.unique
成为名称,导致rbind
失败 .最简单的修复方法是不将字段重命名为重复字段(其中有很多字段),最多为
merge
. 例如:然后
merge
/Reduce
将正常工作 .您可以使用
reshape
包中的merge_all
来执行此操作 . 您可以使用...
参数将参数传递给merge
Here is an excellent resource on different methods to merge data frames .
您可以使用递归来执行此操作 . 我没有验证以下内容,但它应该给你正确的想法:
我将重用@PaulRougieux中的数据示例
这是一个简短而甜蜜的解决方案,使用
purrr
和tidyr
我有一个没有公共id列的数据帧列表 .
我在许多dfs上丢失了数据 . 有Null值 . 数据帧是使用表函数生成的 . Reduce,Merging,rbind,rbind.fill等他们无法帮助我实现目标 . 我的目标是产生一个可理解的合并数据帧,与缺失的数据和常见的id列无关 .
因此,我做了以下功能 . 也许这个功能可以帮助别人 .
它遵循的功能
运行示例