Учитывая ваш комментарий о желании сопоставить слова, вот начало текстового подхода, который может оказаться полезным. По сути, мы хотим выделить каждое слово и посчитать вхождение в каждом утверждении.
library(tidytext)
library(dplyr)
library(tidyr)
dtm <- data %>%
unnest_tokens("word", "animal", token = "regex", pattern = ",") %>%
mutate(word = str_trim(word)) %>%
count(group, word) %>%
pivot_wider(names_from = "word", values_from = "n", values_fill = list(n = 0))
Что вы знаете, так это матрица терминов документа. Теперь мы изменили вашу задачу с регулярного выражения, соответствующего одному, на поиск векторов с наибольшим количеством совпадений.
# A tibble: 4 x 7
group cat dog horse mouse cow frog
<dbl> <int> <int> <int> <int> <int> <int>
1 1 1 1 1 1 0 0
2 2 1 1 1 0 0 0
3 3 1 1 0 0 0 0
4 4 1 1 0 0 1 1
Легче всего было бы извлечь часть матрицы и просто умножить.
mat <- as.matrix(select(dtm, -group))
matches <- (mat %*% t(mat))
Это даст вам матрицу для каждой группы матчей. Например, строка 1, столбец 2 показывает совпадение трех слов (кошка, собака и лошадь) между группами 1 и 2.
matches
[,1] [,2] [,3] [,4]
[1,] 4 3 2 2
[2,] 3 3 2 2
[3,] 2 2 2 2
[4,] 2 2 2 4
Затем вы можете поиграть с вещами оттуда. Например, извлечение идентификаторов строки и столбца, а затем верхней три angular части матрицы может дать вам сводную информацию. Я думаю, что отсюда все зависит от того, как вы хотите отфильтровать таблицу.
data.frame(row = c(row(matches)),
col = c(col(matches)),
value = c(matches),
upper = c(upper.tri(matches))) %>%
filter(upper == TRUE)
row col value upper
1 1 2 3 TRUE
2 1 3 2 TRUE
3 2 3 2 TRUE
4 1 4 2 TRUE
5 2 4 2 TRUE
6 3 4 2 TRUE