我有一个由组组成的数据框,其中对应的动物是一个字符串。
data = data.frame(group = c(1,2,3,4), animal = c("cat, dog, horse, mouse", "cat, dog, horse", "cat, dog,", "cat, dog, frog, cow"))
我想返回字符串最长匹配的组。在这个例子中,组1和组2会匹配,因为4个动物中有3个是相同的。同样,第2组和第3组也会匹配,因为3个动物中有2个是匹配的。但是,没有与第4组匹配的组,因为4个动物中只有2个匹配。
我想返回一个像这样的数据框来显示匹配的组。
group_a group_b
1 2
2 3
我不知道这是否可行。我已经研究了如何匹配部分字符串,但很难找到类似的例子来适应。有什么想法吗?
谢谢你。
这是你要找的吗?
lst <- regmatches(data$animal,gregexpr("\\w+",data$animal))
u <- lapply(seq_along(lst)[-length(lst)],
function(p) subset(data.frame(group_a = p,
group_b = seq_along(lst)[-(1:p)],
longestmatch = sapply(seq_along(lst)[-(1:p)],
function(q) length(intersect(lst[[p]],lst[[q]])))),
longestmatch == max(longestmatch)))
res <- do.call(rbind,c(make.row.names = FALSE,u))
这样
> res
group_a group_b longestmatch
1 1 2 3
2 2 3 2
3 2 4 2
4 3 4 2
鉴于你说的想要匹配单词,这里开始介绍一种文本方法,可能会有帮助。基本上我们要把每个词拆分出来,然后统计每个语句中的出现次数。
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))
你所知道的是一个文档术语矩阵。我们现在已经把你的问题从一个regex匹配的问题变成了寻找匹配度最高的向量。
# 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
然后你就可以从那里玩出东西来。例如,拉出行和列的ID,然后矩阵的上三角部分可以给你一个总结。我想从这里开始就是你想怎么过滤表格的问题了。
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