【问题标题】:Merge multiple rows in a data frame with different values合并具有不同值的数据框中的多行
【发布时间】:2015-03-21 14:06:35
【问题描述】:

我是 R 新手,我想知道如何为大多数列合并具有相同列值的多行。

例如:我有一个数据集:

 v1 v2 v3 v4
      2 3 4 5
      2 3 5 不适用
 

现在,我希望看到结果:

 v1 v2 v3 v4
      2 3 不适用 不适用
 

我希望按原样合并 NA,并将不同的字段转换为 NA。

【问题讨论】:

    标签: r merge duplicates


    【解决方案1】:

    如果你的数据框是df:

    apply(df, 2, function(u) ifelse(length(unique(u))==1, u[1], NA))
    
    #  v1 v2 v3 v4
    #1  2  3 NA NA
    

    回答子问题

    df = data.frame(col1=c(2,2,3),col2=c(3,3,3), col3=c(4,5,5), col4=c(5,NA,NA))
    
    #  col1 col2 col3 col4
    #1    2    3    4    5
    #2    2    3    5   NA
    #3    3    3    5   NA
    
    rbind(apply(df[1:2,], 2, function(u) ifelse(length(unique(u))==1, u[1], NA)), 
          df[3:nrow(df),])
    
    #  col1 col2 col3 col4
    #1    2    3   NA   NA
    #3    3    3    5   NA
    

    【讨论】:

    • lapply 对于data.frame 可能更有意义,但这是一种简单的方法 (+1)。
    • 谢谢@colonel-beauvel。我的下一个问题是:如果我有像上面那样的数据集,但我只想合并那些具有相同 v1 值的行,你建议我怎么做? (例如,假设第三行是 (3,3,5,NA) 那么结果应该包含两行:(2,3,NA,NA) 和 (3,3,5,NA))
    • 答案已编辑,只需使用rbind处理前两行并在处理后与其他行连接!
    • 您的第二部分对行号进行硬编码。基本上,我想要对 col1 进行分组效果。 (我之前应该更清楚,抱歉)
    【解决方案2】:

    我们可以尝试anyDuplicatedsweep 来获得预期的输出

    unique(sweep(df1, 2,  NA^(sapply(df1, anyDuplicated)!=nrow(df1)),'*'))
    #    v1 v2 v3 v4
    #1    2  3 NA NA
    

    更新

    根据@Colonel Beauvel 帖子下的cmets,我们可以从'v1' 的'mode' 创建一个逻辑索引,对数据集进行子集化,执行上述步骤,然后rbind

     df2 <- rbind(df1, c(3,3, 5, NA))
    
     Mode <- function(x) {
       ux <- unique(x)
       ux[which.max(tabulate(match(x, ux)))]
     }
    
     indx <- with(df2, v1==Mode(v1))
     rbind(unique(sweep(df2[indx,], 2, NA^(sapply(df2[indx,], 
               anyDuplicated)!=nrow(df2[indx,])), '*')), df2[!indx,])
     #  v1 v2 v3 v4
     #1  2  3 NA NA
     #3  3  3  5 NA
    

    或者

     df3 <- df2[indx,]
     rbind(sapply(df3, function(x) unique(x * 
                           NA^(anyDuplicated(x)!= nrow(df3)))), df2[!indx,])
      #  v1 v2 v3 v4
      #1  2  3 NA NA
      #3  3  3  5 NA
    

    数据

    df1 <- structure(list(v1 = c(2L, 2L), v2 = c(3L, 3L), v3 = 4:5,
    v4 = c(5L, NA)), .Names = c("v1", "v2", "v3", "v4"),
    class = "data.frame", row.names = c(NA, -2L))
    

    【讨论】:

    • 我收到此错误:“FUN 中的错误(左、右):二进制运算符的非数字参数”
    • @SanthoshHegde 我用我使用的数据更新了帖子
    • 非常牵强和复杂,但扫描很好!
    • @SanthoshHegde 使用 dput 数据集是否仍然出错?
    • @ColonelBeauvel 实际上anyDuplicated 会很快,但复杂之处在于将逻辑索引转换为NAs。感谢您的 cmets。
    【解决方案3】:

    dplyr 包与您的数据框data 一起使用:

    library(dplyr)
    data %>%
      summarise_each(funs(ifelse(length(unique(.))>1,"NA",.)))
    
      v1 v2 v3 v4
    1  2  3 NA NA
    

    如果您想要对某些变量进行分组,而不是合并,您可以将它们指定为分组变量:

    data %>%
      group_by(v1, v2) %>% # the variables you want to group by
      summarise_each(funs(ifelse(length(unique(.))>1,"NA",.)))
    
    Source: local data frame [1 x 4]
    Groups: v1
    
      v1 v2 v3 v4
    1  2  3 NA NA
    

    【讨论】:

    • 谢谢@Sam。我遇到了这个问题。就我而言,有些列是“字符”类,有些是“数字”,有些是“因子”。我正在尝试按 ID 进行分组,这是数字,NA 字段也在数字列上。现在,您的代码给出了一个错误: data %>% + group_by(id) %>% # the variables you want to group by + summarise_each(funs(ifelse(length(unique(.))>1,"NA", .))) 错误:与请求的类型不兼容
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-05-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多