Сумма вхождений слов с несколькими условиями - PullRequest
0 голосов
/ 22 января 2019

Я хочу получить сумму вхождений фруктов, произведенных каждой компанией в предыдущие пять лет, и построить новую колонку со всеми суммами.

Например: в 2016 году company_b произведено яблок;апельсины;груши , в то время как в предыдущие 5 лет компания_b произвела (2011 год: яблоки; апельсины; бананы ) и (2014 год: апельсины; груши ).Подсчитав количество плодов, произведенных в предыдущие пять лет, которые соответствуют целевому (2016) году, мы получаем 4 .

В своем поиске ответа я видел только сумму вхождений для чисел, как в этом сообщении R: вычислить количество вхождений определенного события в указанное время в будущем .Тем не менее, мне нужно посчитать появления всех слов для той или иной компании в предыдущие пять лет.

Любая помощь будет высоко ценится, также приветствуются любые решения, использующие dplyr!:)

df <- data.frame(company=c("company_a","company_b","company_b", "company_a","company_b","company_a"), 
             fruit=c("peaches, apples; oranges","apples; oranges; bananas","oranges; pears","bananas; apples; oranges; pears","apples; oranges; pears","bananas; apples; oranges; pears; peaches"),
             year=c("2010","2011","2014","2014", "2016","2018"))    

> df
    company                                    fruit year
1 company_a                 peaches, apples; oranges 2010
2 company_b                 apples; oranges; bananas 2011
3 company_b                           oranges; pears 2014
4 company_a          bananas; apples; oranges; pears 2014
5 company_b                   apples; oranges; pears 2016
6 company_a bananas; apples; oranges; pears; peaches 2018

Получившийся столбец должен выглядеть следующим образом:

df <-  cbind(df, c("0","0","1","2","4","4") 

company                                    fruit year      sum_occurrences
1 company_a                 peaches, apples; oranges 2010               0
2 company_b                 apples; oranges; bananas 2011               0
3 company_b                           oranges; pears 2014               1
4 company_a          bananas; apples; oranges; pears 2014               2
5 company_b                   apples; oranges; pears 2016               4
6 company_a bananas; apples; oranges; pears; peaches 2018               4       

1 Ответ

0 голосов
/ 22 января 2019
# clean up column classes
df[] <- lapply(df, as.character)
df$year <- as.numeric(df$year)

library(data.table)
setDT(df)

# create separate column for vector of fruits, and year + 5 column
df[, fruit2 := strsplit(gsub(' ', '', fruit), ',|;')]
df[, year2 := year + 5]

# Self join so for each row of df, this creates one row for each time another  
# row is within the year range 
df2 <- df[df, on = .(year <= year2, year > year, company = company)
          , .(company, fruit, fruit2, i.fruit2, year = x.year)]

# For each row in the (company, fruit, year) group, check whether 
# the original fruits are  in the matching rows' fruits, and store the result
# as a logical vector. Then sum the list of logical vectors (one for each row).
df3 <- df2[, .(sum_occurrences = do.call(sum, Map(`%in%`, fruit2, i.fruit2)))
           , by = .(company, fruit, year)]

# Add sum_occurrences to original df with join, and make NAs 0
df[df3, on = .(company, fruit, year), sum_occurrences := i.sum_occurrences]
df[is.na(sum_occurrences), sum_occurrences := 0]

#delete temp columns
df[, `:=`(fruit2 = NULL, year2 = NULL)]

Результат

df


#      company                                    fruit year sum_occurrences
# 1: company_a                 peaches, apples; oranges 2010               0
# 2: company_b                 apples; oranges; bananas 2011               0
# 3: company_b                           oranges; pears 2014               1
# 4: company_a          bananas; apples; oranges; pears 2014               2
# 5: company_b                   apples; oranges; pears 2016               4
# 6: company_a bananas; apples; oranges; pears; peaches 2018               4
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...