如果字符串包含R中的特定文本,则进行聚合

时间:2017-02-13 15:50:44

标签: r sum aggregate

我已经看过很多关于这个话题的帖子,如果这是重复的话我会道歉,但我无法弄清楚我的问题。

我有

df <- data.frame(name = c('bike+ride','shoe+store','ride','mountian%20bike','ride+along'),
             count = c(2,5,8,7,6))

如果count包含字符串name

,则希望对每个group求和
group <- data.frame(group = c('ride','bike'))

所以最终结果如下:

Group   Count
bike      9
ride     16

有人可以帮忙吗?

3 个答案:

答案 0 :(得分:3)

基础R想法,

sapply(sapply(as.character(group$group), function(i) grep(i, df$name)), function(i) sum(df$count[i]))


#or make it a function

aggr1 <- function(var1, grp, cnt){
  m1 <- sapply(as.character(grp), function(i) grep(i, var1))
  final_d <- sapply(m1, function(i) sum(cnt[i]))
  return(data.frame(Group = names(final_d), 
                    Count = as.integer(final_d), stringsAsFactors = FALSE)
         )
}

aggr1(df$name, group$group, df$count)

#  Group Count
#1  ride    16
#2  bike     9

答案 1 :(得分:1)

一种方法是

do.call(rbind, sapply(group$group, FUN = function(x, df) {
  out <- df[grepl(pattern = x, x = df$name), ]
  data.frame(group = x, count = sum(out$count))
}, df = df, simplify = FALSE))

  group count
1  ride    16
2  bike     9

分两步:

# make a data.frame which locates where each group level is located
grp <- as.data.frame(sapply(group$group, FUN = function(x) grepl(pattern = x, x = df$name)))
names(grp) <- group$group

# based on above location (TRUE/FALSE), sum accordingly
data.frame(count = apply(grp, MARGIN = 2, FUN = function(x, df) {
  sum(df[x, "count"])
}, df = df))

     count
ride    16
bike     9

答案 2 :(得分:0)

使用tidyverse个包purrrdplyrtidyr的方式:

library(tidyverse) # for dplyr, purr and tidyr

groups <- c('ride','bike')

map_df(groups, ~setNames(summarize_(df, interp(~sum(df$count[grepl(var, name)], na.rm = TRUE), var = .x)), .x)) %>% 
      gather(group, count, na.rm = TRUE)