折叠数据框中的行,同时合并另一个列值

时间:2013-07-17 18:24:32

标签: r merge dataframe plyr reshape2

我有这些数据集

d1 = data.frame(PatID=c(1,1,1,2,2,4,1,2), 
                code1=c(1,2,3,1,2,7,2,8), 
                location=c('a','b','c','d','e','f','g','h'))

我想消除重复的行(PatID),所以

  1. 每个唯一PatID只能获得一行;
  2. 为所有公共行合并code1的值
  3. 保留任何一个匹配行的位置(对于第一行或最后一行 - 无关紧要)。
  4. 输出应为:

    PatID    code1    location 
    1        1,2,3    a 
    2        1,2,8    d 
    4        7        f 
    

    我尝试过聚合失败,ddply甚至与融化dcast挣扎。我是前unix程序员,但是的新手。

2 个答案:

答案 0 :(得分:4)

ddply效果很好:

ddply(d1,.(PatID),
      summarise,
      code1 = paste(unique(code1),collapse = ','),
      location = location[1])

  PatID code1 location
1     1 1,2,3        a
2     2 1,2,8        d
3     4     7        f

哦好的。这是data.table版本:

d2 <- as.data.table(d1)
> d2[,list(code1 = paste(unique(code1),collapse = ','),location = location[1]),by = 'PatID']
   PatID code1 location
1:     1 1,2,3        a
2:     2 1,2,8        d
3:     4     7        f

答案 1 :(得分:1)

只是为了确保基本R不会被完全忽略(或者让你欣赏这些类型问题的“plyr”和“data.table”的语法)...

两个选项:

选项1:使用ave执行“聚合”,使用unique减少输出

unique(within(d1, {
  code1 <- ave(code1, PatID, 
               FUN=function(x) paste(unique(x), collapse = ","))
  location <- ave(location, PatID, FUN=function(x) x[1])
}))
#   PatID code1 location
# 1     1 1,2,3        a
# 4     2 1,2,8        d
# 6     4     7        f

选项2:让aggregatemerge一起工作

merge(
  aggregate(code1 ~ PatID, d1, 
          function(x) paste(unique(x), collapse = ",")),
  aggregate(location ~ PatID, d1, function(x) x[1]))
#   PatID code1 location
# 1     1 1,2,3        a
# 2     2 1,2,8        d
# 3     4     7        f

我能想到的最接近的纯aggregate解决方案如下:

aggregate(cbind(code1, as.character(location)) ~ PatID, d1, 
          function(x) cbind(paste(unique(x), collapse = ","),
                            as.character(x[1])))
#   PatID code1.1 code1.2    V2.1 V2.2
# 1     1   1,2,3       1 a,b,c,g    a
# 2     2   1,2,8       1   d,e,h    d
# 3     4       7       7       f    f

它为您提供了您感兴趣的所有信息,以及您不感兴趣的大量信息......