Существует ли R-метод для group_by, поиска и сопоставления длинной структуры данных?

#r #boolean #match #tidyverse #text-mining

#r #логическое значение #сопоставление #tidyverse #интеллектуальный анализ текста

Вопрос:

Это проблема поиска того, какие id слова имеют совпадающие word значения, из списка по 5 слов для каждого id .

У нас есть длинная структура данных из проекта интеллектуального анализа текста с id и word . Каждый group_id содержит 5 слов. Мы хотели бы измерить, какие word идентификаторы из одного идентификатора находятся в другом id . т. Е. Какие идентификаторы похожи на основе этих слов.

Мы пытались использовать цикл for для [строка, столбец], но, похоже, есть способ получше.

 library(tidyverse)

data <- tibble(id = factor(c(1234, 1234, 1234, 1234, 1234, 
                             4523, 4523, 4523, 4523, 4523, 
                             0984, 0984, 0984, 0984, 0984)),
       word = c("hello", "today", "the", "monkey", "boy",
                "go", "me", "key", "wind", "hello",
                "monkey", "yes", "no", "wild", "quit"))


output <- matrix(1, length(data$id), length(data$id))

for (j in 1 : length(data$id)) {
  for (i in 1 : length(data$id)) {
    output[i,j] <-  data[i,2] == data[j,2]

  }
}

output

## from the output we see that 4 and 11 match.

data[4,]
data[11,]

  

Моя конечная цель — получить матрицу с id by id , а пересечения — это количество совпадающих слов (0-5).

Это желаемый результат:

 #      1234 4523 0984 
# 1234    5    1    1  
# 4523    1    5    0  
# 0984    1    0    5 
  

Приветствуются любые предложения по полной реорганизации структуры данных или решения с этой структурой. Спасибо!

Ответ №1:

Мы можем split word с помощью id пользовательской функции, а затем использовать outer с пользовательской функцией для вычисления количества раз, когда слово встречается между разными id s.

 count_value <- function(x, y) {
    colSums(mapply(`%in%`, x, y))
}

outer(split(data$word, data$id),split(data$word, data$id), count_value)

#     984 1234 4523
#984    5    1    0
#1234   1    5    1
#4523   0    1    5
  

Комментарии:

1. хотя я хотел бы использовать group_by id и посмотреть, сколько слов для каждого id соответствует другому id

2. Я добавил пример вывода, показывающий количество совпадений word между каждым id

Ответ №2:

Мы можем легко решить это с помощью tcrossprod из base R

 tcrossprod(table(data))
#   id
#id     984 1234 4523
#  984    5    1    0
#  1234   1    5    1
#  4523   0    1    5
  

Или тот же метод с tidyverse

 library(tidyverse)
count(data, id, word) %>%
     spread(word, n, fill = 0) %>%
     column_to_rownames('id') %>% 
     as.matrix %>% 
     tcrossprod
#      984 1234 4523
#984    5    1    0
#1234   1    5    1
#4523   0    1    5