Как мне сгенерировать нграммы в фрейме данных, чтобы каждая нграмма создавала новую строку?

#r #multiple-columns #sapply

#r #несколько столбцов #sapply

Вопрос:

Я пытаюсь использовать ngram_asweka для идентификации нграмм в символьном векторе, построчно, сохраняя при этом такие данные, как номер элемента, участник / контроль и т.д. Я пробовал tapply и sapply, но безуспешно. В моем фрейме данных больше столбцов, но базовый формат выглядит следующим образом:

Элемент Фраза
1. Кошки и собаки
2. птицы и пчелы

Мне нужно, чтобы он выводил

Элемент Фраза Нграм
1. Кошки и собаки кошки и собаки
1. Кошки и собаки кошки и
1. Кошки и собаки и собаки
2. птицы и пчелы птицы и пчелы
2. птицы и пчелы птицы и

Это моя функция ngram

 myngram <-function(x) {
  x<- ngram_asweka(x, min = 2, max = 5, sep = " ") %>% data.frame()
  return(x)
 

И вот код, который я пробовал, который не работает.

 x<-tapply(df$phrase, df$ID, myngram) %>% data.frame()
 

Код ошибки гласит: «Ошибка в ngram_asweka (x, min = 2, max = 5, sep = » «): попытка установить индекс 2/2 в SET_STRING_ELT

Спасибо за вашу помощь.

Ответ №1:

В вашем примере для тестирования вам может потребоваться max = 3 ngram_asweka , учитывая, что длина строк составляет всего 3 слова (3 грамма).

Вот один из вариантов использования tidyverse . Вы можете использовать group_by для получения результатов для каждого item и group_modify для создания строк результатов, включая фразу и n-граммы.

 library(tidyverse)
library(ngram)

df %>%
  group_by(item) %>%
  group_modify(function(x, y) 
     tibble(phrase = x$phrase,
            ngram = ngram_asweka(x$phrase, min = 2, max = 3, sep = " ")))
 

Если у вас есть другие столбцы, которые вы хотите включить в вывод с большим набором данных, вы можете выполнить следующую альтернативу:

 df %>%
  group_by(item) %>%
  group_modify(~ bind_cols(select(.x, everything()),
                           ngram = ngram_asweka(.x$phrase, min = 2, max = 3, sep = " ")))
 

Вывод

    item phrase         ngram         
  <dbl> <chr>          <chr>         
1     1 Cats and dogs  Cats and dogs 
2     1 Cats and dogs  Cats and      
3     1 Cats and dogs  and dogs      
4     2 birds and bees birds and bees
5     2 birds and bees birds and     
6     2 birds and bees and bees  
 

Данные

 df <- structure(list(item = c(1, 2), phrase = c("Cats and dogs", "birds and bees"
)), class = "data.frame", row.names = c(NA, -2L))