2017-02-13 11 views
4

Я видел много сообщений на эту тему, поэтому извиняюсь, если это дубликат, но я не мог понять свою проблему.Совокупность, если строка содержит определенный текст в R

У меня есть

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

Основание 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 
+0

благодарит за вашу помощь. Любая идея, как я буду обрабатывать экземпляры, где имя включает символы sich как '+' или '% 20'? – Davis

+0

В вашем примере у вас есть эти символы в имени, и он работает так, как ожидалось. – Sotos

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 
+0

Некоторые улучшения скорости, если можно? 'data.frame (group = group, count = sapply (group $ group, FUN = function (x) sum (df [grepl (pattern = x, x = df $ name, fixed = TRUE)," count "]))) '(нет необходимости в' do.call' или создании 'data.frame' в каждой итерации, добавляя' fixed = TRUE' и т. д.) –

0

Способ использования tidyverse пакетов purrr, dplyr и tidyr:

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) 
+0

Это кажется довольно пешеходным, когда дело доходит до включения дополнительных уровней 'group $ group' , –

+0

Согласен. Изменен ответ на включение дополнительных уровней. –