Conte a frequência das palavras do dicionário em uma coluna e gere uma nova coluna “dictfreq”

Nov 24 2020

Parece um comando simples, mas não consigo encontrar uma boa maneira de gerá-lo em R. Basicamente, quero apenas contar a frequência de cada palavra em um dicionário, dict, dentro de outra coluna de dataframe, wordsgov:

dict = "apple", "pineapple","pear"
df$wordsgov = "i hate apple", "i hate apple", "i love pear", "i don't like pear", "pear is okay", "i eat pineapple sometimes"

saída desejada: nova classificação de frequência, mostrando todas as palavras em dict de acordo com sua frequência em df $ wordsgov

dict    freq_gov
"pear" : 3
"apple": 2
"pineapple: 1

Tentei o seguinte código, mas ele me deu a contagem de quantas vezes as palavras de dict aparecem em cada linha de df $ wordgov, que não é o que eu quero:

dictongov <- within(
  df,
  counts <- sapply(
    gregexpr(paste0(dict, collapse = "|"), wordsgov),
    function(x) sum(x > 0)
  )
)

Não consigo descobrir como alterar a função para que ela me forneça a frequência para cada palavra do dict em dict $ wordsgov. Eu tentei str_detect, mas também não está funcionando. qualquer ajuda seria muito apreciada !!!

- editar: usei o seguinte, que funcionou bem.

dictfreq <- df %>% mutate(dict = str_c(str_extract(wordsgov, str_c(dict, collapse = '|')), ':')) %>% 
                   count(dict, name = 'freq_gov') %>% arrange(desc(freq_gov))

no entanto, retirou todas as palavras que tinham frequência 0. existe alguma forma de manter as palavras com frequência 0? Eu tentei ".drop = FALSE", mas não parece estar funcionando dentro deste código. Qualquer ajuda seria muito apreciada. obrigado!

Respostas

akrun Nov 24 2020 at 21:50

Também podemos fazer isso com str_count

library(stringr)
library(purrr)
out <- map_int(str_c("\\b", v2, "\\b"), ~  sum(str_count(v1, .x)))
out
#[1] 2 1 3

rank(out)

dados

v1 <- c("i hate apple", "i hate apple", "i love pear", "i don't like pear", 
       "pear is okay", "i eat pineapple sometimes")

v2 <- c("apple", "pineapple", "pear")