#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