查找具有最长匹配字符串的行

问题描述 投票:0回答:1

我有一个由组组成的数据框,其中对应的动物是一个字符串。

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

我不知道这是否可行。我已经研究了如何匹配部分字符串,但很难找到类似的例子来适应。有什么想法吗?

谢谢你。

r string matching longest-substring
1个回答
1
投票

这是你要找的吗?

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

1
投票

鉴于你说的想要匹配单词,这里开始介绍一种文本方法,可能会有帮助。基本上我们要把每个词拆分出来,然后统计每个语句中的出现次数。

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
© www.soinside.com 2019 - 2024. All rights reserved.