【问题标题】:Merging and summarizing two dataframes合并和总结两个数据框
【发布时间】:2016-08-15 22:12:46
【问题描述】:

我有以下数据:

a <- data.frame(ID=c("A","B","Z","H"), a=c(0,1,2,45), b=c(3,4,5,22), c=c(6,7,8,3))
> a
  ID  a  b c
1  A  0  3 6
2  B  1  4 7
3  Z  2  5 8
4  H 45 22 3

b <- data.frame(ID=c("A","B","E","W","Z","H"), a=c(9,10,11,39,5,0), b=c(4,2,7,54,12,34), c=c(12,0,34,23,13,14))

> b
   ID  a  b  c
1:  A  9  4 12
2:  B 10  2  0
3:  E 11  7 34
4:  W 39 54 23
5:  Z  5 12 13
6:  H  0 34 14

我想合并两个数据框,只保留 data.frame a 的行并汇总相同的列,所以最后我得到:

> z
  ID  a   b   c
1  A  9   7  18
2  B 11   6   7
3  Z  7  17  21
4  H 45  56  17

到目前为止,我已经尝试了以下方法:

merge(a,b,by="ID",all.x=T,all.y=F)
> merge(a,b,by="ID",all.x=T,all.y=F)
  ID a.x b.x c.x a.y b.y c.y
1  A   0   3   6   9   4  12
2  B   1   4   7  10   2   0
3  H  45  22   3   0  34  14
4  Z   2   5   8   5  12  13

> join(a,b,type="left",by="ID")
  ID  a  b c  a  b  c
1  A  0  3 6  9  4 12
2  B  1  4 7 10  2  0
3  Z  2  5 8  5 12 13
4  H 45 22 3  0 34 14

我无法总结这些列。

我的数据框非常大,所以如果解决方案可以加快速度,那就更好了。

【问题讨论】:

    标签: r dataframe merge


    【解决方案1】:

    如果你的 data.frame 很大,那么你可以考虑这个选项:

    library(data.table)
    
    ## convert data.frame to data.table
    setDT(a)
    
    ## convert data.frame to data.table
    setDT(b)
    
    ## merge the two data.tables
    c <- merge(a,b,by='ID')
    
    ## extract names of all columns except the first one i.e. ID
    col_names <- colnames(a)[-1]
    
    ## query building
    col_1 <- paste0(col_names,'.x')
    
    col_2 <- paste0(col_names,'.y')
    
    cols <- paste(col_1,col_2,sep=',')
    
    cols_2 <- paste0(col_names," = sum(",cols,")")
    
    cols_3 <- paste(cols_2,collapse=',')
    
    query <- paste0("z <- c[,.(",cols_3,"),by=ID]")
    
    ## query execution
    eval(parse(text = query))
    

    【讨论】:

      【解决方案2】:

      这至少适用于您的示例:

      a <- data.frame(ID=c("A","B","Z","H"), a=c(0,1,2,45), b=c(3,4,5,22), c=c(6,7,8,3))
      b <- data.frame(ID=c("A","B","E","W","Z","H"), a=c(9,10,11,39,5,0), b=c(4,2,7,54,12,34), c=c(12,0,34,23,13,14))
      
      match_a <- na.omit(match(b$ID, a$ID))
      match_b <- na.omit(match(a$ID, b$ID))
      
      df <- cbind(ID = a$ID[match_a], a[match_a, -1] + b[match_b, -1])
      

      首先,从ab 中获取匹配的行,反之亦然,因此我们可以确定我们只有那些出现在两个数据帧中的行(我们现在知道它们在两个数据帧中的行索引)。然后,对那些匹配的行简单地使用向量化加法,但省略ID,因为factor不能被总结;手动添加ID

      【讨论】:

        【解决方案3】:

        您不能直接添加两个数据框,因为两个数据框的大小不相等。为了使它们大小相等,您可以检查 a 中的 IDs,它们存在于 b 中,然后将它们添加到元素中。

        new <- b[b$ID %in% a$ID, ]
        cbind(ID = a$ID, a[-1] + new[-1])
        
        #  ID  a  b  c
        #1  A  9  7 18
        #2  B 11  6  7
        #3  Z  7 17 21
        #4  H 45 56 17
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2019-04-28
          • 1970-01-01
          • 2012-10-08
          • 2017-08-15
          相关资源
          最近更新 更多