如何合并和聚合3个不同长度和字母的数据帧

时间:2015-01-14 03:17:00

标签: r merge dataframe aggregate

我有三个结构相似的数据框,但有一个不同的列名和不同的行数。

> a
        ID count    alpha
1      207     1        1
2      351     1        1
3      372     1        1
4      595     4        1
5      596     1        1
6      652     1        1

> b
        ID count     beta
1      207     1        1
2      351     1        1
3      372     1        1
4     1024     6        1

> c
        ID count     zeta
1      207     4        1
2      351     1        1
3      372     1        1
4      595     2        1

我需要创建一个包含所有列(id,count,alpha,beta)的新数据框,同时输出count的总和。如果ID仅显示在一个数据帧中,则它应在相应列中输出0。所需的输出如下:

> abc
        ID count    alpha    beta    zeta
1      207     6        1       1       1
2      351     3        1       1       1
3      372     3        1       1       1
4      595     6        1       0       1
5      596     1        1       0       0
6      652     1        1       0       0
7     1024     6        0       1       0

我在a和b上尝试了merge()并得到了这个输出:

> merge(a, b, by=intersect(names(a),names(b)), all=TRUE, sort=TRUE)
    id count alpha beta
1  207     1     1    1
2  351     1     1    1
3  372     1     1    1
4  595     4     1   NA
5  596     1     1   NA
6  652     1     1   NA
7 1024     6    NA    1

我可以告诉他们0岁了但是这个输出有两个主要问题:

(1)计数列未加总

(2)merge()仅使用2个数据帧,实际上我有更多(如10)

欢迎任何建议。

2 个答案:

答案 0 :(得分:2)

以下是我如何做到这一点:

  1. 创建相关list的{​​{1}}(就像将它们全部放入data.frame一样简单。
  2. 使用list()(或其他增强型rbindlist功能之一,即使列不同,也可以按行将数据集绑定在一起 - 请参阅“plyr”和“dplyr”代表rbind)的其他常见替代品。
  3. 在这里,我使用了“data.table”中的rbindlist

    rbindlist

    我不确定这是否正是您想要处理“alpha”,“beta”,...列的方式。我刚刚总结了一切。


    本回答中使用的示例数据:

    library(data.table)
    rbindlist(list(a, b, c), use.names = TRUE, fill = TRUE)[
      , lapply(.SD, sum, na.rm = TRUE), by = ID]
    #      ID count alpha beta zeta
    # 1:  207     6     1    1    1
    # 2:  351     3     1    1    1
    # 3:  372     3     1    1    1
    # 4:  595     6     1    0    1
    # 5:  596     1     1    0    0
    # 6:  652     1     1    0    0
    # 7: 1024     6     0    1    0
    

答案 1 :(得分:1)

这可以分阶段dplyr完成。

鉴于数据:

dfA <- data.frame(c(207, 351, 372, 595, 596, 652), c(1, 1, 1, 4, 1, 1), rep(1, 6))
names(dfA) <- c('ID', 'count', 'alpha')
dfB <- data.frame(c(207, 351, 372, 1024), c(1, 1, 1, 6), rep(1, 4))
names(dfB) <- c('ID', 'count', 'beta')
dfC <- data.frame(c(207, 351, 372, 595), c(4, 1, 1, 2), rep(1, 4))
names(dfC) <- c('ID', 'count', 'zeta')

以下虽然有些丑陋,但仍有效:

library(dplyr)
dfT <- bind_rows(dfA, dfB, dfC)
df_1 <- dfT %>% group_by(ID) %>% summarise(sum(count))
df_F <- data.frame(df_1, as.numeric(df_i$ID %in% dfA$ID), as.numeric(df_i$ID %in% dfB$ID), as.numeric(df_i$ID %in% dfC$ID))
names(df_F) <- c("ID", "count", "alpha", "beta", "zeta")

> df_F
    ID count alpha beta zeta
1  207     6     1    1    1
2  351     3     1    1    1
3  372     3     1    1    1
4  595     6     1    0    1
5  596     1     1    0    0
6  652     1     1    0    0
7 1024     6     0    1    0