根据R中的匹配条件组合行中的值

时间:2015-04-07 20:18:52

标签: r dataframe

我有一个关于在R中聚合值的简单问题。

假设我有一个数据帧:

DF <- data.frame(col1=c("Type 1", "Type 1B", "Type 2"), col2=c(1, 2, 3))  

看起来像这样:

     col1 col2
1  Type 1    1
2 Type 1B    2
3  Type 2    3

我注意到数据中有Type 1Type 1B,因此我想将Type 1B合并到Type 1中。

所以我决定使用dplyr

filter(DF, col1=='Type 1' | col1=='Type 1B') %>%
  summarise(n = sum(col2))

但现在我需要坚持下去:

DF2 <- data.frame('Type 1', filter(DF, col1=='Type 1' | col1=='Type 1B') %>%
  summarise(n = sum(col2)))

我想我想cbind这个新的DF2回到原来的DF,但这意味着我必须将列名设置为一致:

names(DF2) <- c('col1', 'col2')

好的,现在我可以回复:

rbind(DF2, DF[3,])

结果呢?它起作用....

   col1 col2
1 Type 1    3
3 Type 2    3

......但是唉!太糟糕了!必须有一种更好的方法来简单地组合价值观。

4 个答案:

答案 0 :(得分:4)

这是一种可能的dplyr方法:

library(dplyr)
DF %>%
  group_by(col1 = sub("(.*\\d+).*$", "\\1", col1)) %>%
  summarise(col2 = sum(col2))
#Source: local data frame [2 x 2]
#
#    col1 col2
#1 Type 1    3
#2 Type 2    3

答案 1 :(得分:4)

sub()aggregate()一起使用,从col1的末尾删除除数字以外的任何内容,

do.call("data.frame", 
    aggregate(col2 ~ cbind(col1 = sub("\\D+$", "", col1)), DF, sum)
)
#     col1 col2
# 1 Type 1    3
# 2 Type 2    3

do.call()包装器在那里,以便aggregate()之后的第一列从矩阵正确地更改为向量。这样,以后就不会有任何意外。

答案 2 :(得分:2)

您可以尝试:

library(data.table)

setDT(transform(DF, col1=gsub("(.*)[A-Z]+$","\\1",DF$col1)))[,list(col2=sum(col2)),col1]

#      col1 col2
# 1: Type 1    3
# 2: Type 2    3

甚至更直接:

setDT(DF)[, .(col2 = sum(col2)), by = .(col1 = sub("[[:alpha:]]+$", "", col1))]

答案 3 :(得分:1)

在我看来,aggregate()是完成此功能的完美功能,但您不应该进行任何文字处理(例如gsub())。我会分两步完成这个过程:

  1. 使用新的所需分组覆盖col1
  2. 使用新的col1计算聚合以指定分组。

  3. DF$col1 <- ifelse(DF$col1 %in% c('Type 1','Type 1B'),'Type 1',levels(DF$col1));
    DF;
    ##     col1 col2
    ## 1 Type 1    1
    ## 2 Type 1    2
    ## 3 Type 2    3
    DF <- aggregate(col2~col1, DF, FUN=sum );
    DF;
    ##     col1 col2
    ## 1 Type 1    3
    ## 2 Type 2    3