合并数据框,同时对 R 中的公共列求和

Evi*_*ebl 5 merge r

我的问题与此处发布的问题非常相似。

不同之处在于他们知道会发生冲突的列,而我需要一种通用方法,该方法不会事先知道哪些列会发生冲突。

例子:

TABLE1
Date             Time    ColumnA    ColumnB
01/01/2013      08:00      10         30
01/01/2013      08:30      15         25
01/01/2013      09:00      20         20
02/01/2013      08:00      25         15
02/01/2013      08:30      30         10
02/01/2013      09:00      35         5

TABLE2
Date           ColumnA    ColumnB    ColumnC
01/01/2013      100        300         1
02/01/2013      200        400         2
Run Code Online (Sandbox Code Playgroud)

表 2 只有日期,因此适用于表 A 中与日期匹配的所有字段,而不考虑时间。

我希望合并将冲突的列相加为 1。结果应如下所示:

TABLE3
Date             Time    ColumnA    ColumnB    ColumnC
01/01/2013      08:00      110         330        1
01/01/2013      08:30      115         325        1
01/01/2013      09:00      120         320        1
02/01/2013      08:00      225         415        2
02/01/2013      08:30      230         410        2
02/01/2013      09:00      235         405        2
Run Code Online (Sandbox Code Playgroud)

目前我的标准合并只是创建了“ColumnA.x”、“ColumnA.y”、“ColumnB.x”、“ColumnB.y”的重复列。

任何帮助深表感谢

Din*_*nre 4

如果我理解正确,您需要一种灵活的方法,除了要合并的列和要保留的列之外,不需要知道每个表中存在哪些列。这可能不是最优雅的解决方案,但这里有一个示例函数可以满足您的具体需求:

merge_Sum <- function(.df1, .df2, .id_Columns, .match_Columns){
    merged_Columns <- unique(c(names(.df1),names(.df2)))
    merged_df1 <- data.frame(matrix(nrow=nrow(.df1), ncol=length(merged_Columns)))
    names(merged_df1) <- merged_Columns
    for (column in merged_Columns){
        if(column %in% .id_Columns | !column %in% names(.df2)){
            merged_df1[, column] <- .df1[, column]
        } else if (!column %in% names(.df1)){
            merged_df1[, column] <- .df2[match(.df1[, .match_Columns],.df2[, .match_Columns]), column]
        } else {
            df1_Values=.df1[, column]
            df2_Values=.df2[match(.df1[, .match_Columns],.df2[, .match_Columns]), column]
            df2_Values[is.na(df2_Values)] <- 0
            merged_df1[, column] <- df1_Values + df2_Values
        }
    }
    return(merged_df1)
}
Run Code Online (Sandbox Code Playgroud)

此函数假设您有一个主表“.df1”,并且您想要合并第二个表“.df2”中的数据,该表的行与“.df1”中的一个或多个行相匹配。主表“.df1”中要保留的列被接受为数组“.id_Columns”,提供用于合并两个表的匹配的列被接受为数组“.match_Columns”

对于您的示例,它将像这样工作:

merge_Sum(table1, table2, c("Date","Time"), "Date")

#   Date       Time  ColumnA ColumnB ColumnC
# 1 01/01/2013 08:00     110     330       1
# 2 01/01/2013 08:30     115     325       1
# 3 01/01/2013 09:00     120     320       1
# 4 02/01/2013 08:00     225     415       2
# 5 02/01/2013 08:30     230     410       2
# 6 02/01/2013 09:00     235     405       2
Run Code Online (Sandbox Code Playgroud)

用简单的语言来说,该函数首先查找唯一列的总数,并以主表“.df1”的形式创建一个空数据框,以稍后保存合并的数据。然后,对于“.id_Columns”,数据从“.df1”复制到新的合并数据框中。对于其他列,“.df1”中存在的任何数据都会添加到“.df2”中的任何现有数据,其中“.df2”中的行根据“.match_Columns”进行匹配

可能有一些包可以做类似的事情,但大多数都需要了解所有现有的列以及如何处理它们。正如我之前所说,这不是最优雅的解决方案,但它是灵活且准确的。

更新:原始函数假设 table1 和 table2 之间存在多对一关系,并且 OP 也请求允许多对无关系。代码已更新,效率稍低,但逻辑灵活 100%。