2016-01-04 1 views
0

У меня есть кадр данных, который выглядит немного как это:Как суммировать (dplyr) colums путем получения 10 лучших биграмм (ngrams) для каждой группы?

df <- structure(list(group = structure(c(1L, 1L, 2L, 2L), .Label = c("1", 
"2"), class = "factor"), text = structure(c(2L, 1L, 4L, 3L), .Label = c("hello hi four five", 
"hi hello one two three", "one three four five", "one two three" 
), class = "factor")), .Names = c("group", "text"), row.names = c(NA, 
-4L), class = "data.frame") 

df 
    group     text 
1  1 hi hello one two three 
2  1  hello hi four five 
3  2   one two three 
4  2 one three four five 

Теперь я хочу подвести итог этого кадра данных путем извлечения сверху (максимум 10) bibrams в каждой группе.

Нечто подобное (make_bigrams мнимая функция):

df <- group_by(df, group) 
summarise(df, make_bigrams(text)) 

Результат должен быть что-то вроде этого:

group       text 
1  1 hi_hello, hi_one, hi_two_etc. 
2  2  one_three, one_two, etc. 

Я попытался функции, как Tokenizer из RWeka, но никто не сделал ват Я намеревался. У кого-нибудь есть идея? Спасибо заранее!

+0

cf http://tm.r-forge.r-project.org/faq.html#Bigrams. Тем не менее, вы, кажется, хотите, чтобы каждое совместное происхождение, а не только bigrams (например, hi_one в первой группе: два слова никогда не встречаются один за другим). – scoa

+0

Правильно, мне нужно каждое совместное происшествие. Я проверю ссылку. – rdatasculptor

+0

Я все попробовал 'ngrams (words (x), 2)', но каким-то образом я не смог заставить эту функцию работать должным образом в контексте summary() (dplyr). – rdatasculptor

ответ

1

Вот что вы могли бы сделать для биграмм (т. Е. Смежных подпоследовательностей длины n ", где n = 2 в соответствии с ?NLP::ngrams).

library(tm) # for corpus and dtm; loads NLP 
library(dplyr)  
library(tidyr) 

df$text <- as.character(df$text) 

## numbering documents 
df$doc <- factor(1:nrow(df)) 


corpus <- Corpus(VectorSource(df$text)) 
# function source: tm.r-forge.r-project.org/faq.html#Bigrams 
BigramTokenizer <- 
    function(x) 
    unlist(lapply(ngrams(words(x), 2), paste, collapse = "_"), use.names = FALSE) 

## create a Term Document Matrix of bigrams 
tdm <- TermDocumentMatrix(corpus, control = list(tokenize = BigramTokenizer)) 

## Let's find the most frequent for each group 
as.data.frame.matrix(tdm) %>%   # transform to df 
    add_rownames() %>%     # we need the words 
    gather(doc,value,-rowname) %>%  # convert to long form 
    filter(value != 0) %>%    # remove bigrams not in document 
    left_join(df[,c("doc","group")]) %>% # match doc number with group number 
    group_by(group,rowname) %>%   # grouping 
    summarise(n=sum(value)) %>%   # find out the number of bigrams by group 
    arrange(desc(n)) %>%     # sort the data by most frequently found bigrams 
    slice(1:10) %>%      # select only the 10 most frequent in each group 
    summarize(most_frequent_bigrams=paste(rowname,collapse = ", ")) # format this to a single string 
+0

Спасибо! Как вы думаете, я могу обернуть это в одну функцию, которую я могу вызвать в функции суммирования? – rdatasculptor

+0

Что вы имеете в виду? Это решение уже использует обобщение. Если вы присвойте результат новому кадру data.frame, вы можете использовать его как хотите (объединить его с вашим источником и т. Д.) – scoa

+0

Я надеялся, что смогу сделать что-то вроде 'summaryize (df, bigrams = get_top10_bigrams (text)) 'и что он запускает весь ваш код в одной функции. – rdatasculptor

Смежные вопросы