为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

森林海 2019-05-27 10:31:03
同时合并列表中的多个data.frames我有一个我要合并的许多data.frames的列表。这里的问题是每个data.frame在行数和列数方面都不同,但它们都共享关键变量(我已经调用过"var1","var2"在下面的代码中)。如果data.frames在列方面是相同的,我只能rbind,plyr的rbind.fill可以完成这项工作,但这些数据并非如此。因为该merge命令仅适用于2个data.frames,所以我转向Internet寻求创意。我从这里得到了这个,它在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(很明显,我在其他地方看到了其他对此错误的引用而没有解决方案)。有什么方法可以解决这个问题吗?
查看完整描述

4 回答

?
SMILET

TA贡献1796条经验 获得超4个赞

另一个问题具体询问如何在R中使用dplyr执行多个左连接。这个问题被标记为这个问题的副本,所以我在这里回答,使用下面的3个示例数据框:

library(dplyr)

x <- data_frame(i = c("a","b","c"), j = 1:3)

y <- data_frame(i = c("b","c","d"), k = 4:6)

z <- data_frame(i = c("c","d","a"), l = 7:9)

更新2018年6月:我将答案分为三个部分,分别代表三种不同的合并方式。purrr如果您已经在使用tidyverse软件包,那么您可能希望使用这种方式。为了进行比较,您将找到使用相同样本数据集的基本R版本。


reduce从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

您还可以执行其他连接,例如a full_join或inner_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

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

基础R merge()与基础RReduce()

为了进行比较,这里是左连接的基本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


查看完整回答
反对 回复 2019-05-27
?
ibeautiful

TA贡献1993条经验 获得超5个赞

您可以merge_allreshape包中使用它。您可以传递参数以merge使用...参数

reshape::merge_all(list_of_dataframes, ...)

这是合并数据帧的不同方法的优秀资源


查看完整回答
反对 回复 2019-05-27
?
蛊毒传说

TA贡献1895条经验 获得超3个赞

您可以使用递归来执行此操作。我没有验证以下内容,但它应该给你正确的想法:

MergeListOfDf = function( data , ... ){
    if ( length( data ) == 2 ) 
    {
        return( merge( data[[ 1 ]] , data[[ 2 ]] , ... ) )
    }    
    return( merge( MergeListOfDf( data[ -1 ] , ... ) , data[[ 1 ]] , ... ) )}


查看完整回答
反对 回复 2019-05-27
  • 4 回答
  • 0 关注
  • 1508 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信