查找字符串列表的每个元素与 R 中向量的每个字符串之间的匹配项(避免 'for')

Finding matches between each element of a list of strings and each string of a vector in R (avoiding 'for')

我在数据框中有两列要比较的字符串。第一个是字符串向量,第二个是一个列表,每个元素中都有一个迷你字符串向量。想象一下有这样一个数据框:

    V                 L 
"Anameone"     "name" "asd" 
"Bnametwo"         "dfg"
"Cnamethree"   "hey" "C" "hi"

我想看看L的第一个元素中的某些词是否出现在V的第一个元素中,L的第二个元素中的某些词是否出现在V的第二个元素中...等等。

我可以用这样的循环做我想做的事:

for (i in c(1:3)){ df$matches[i] <- any(df$L[[i]],grepl, df$V[i],ignore.case = T)) }

所以输出是:

> df$matches
[1] "TRUE"  "FALSE" "TRUE"

但实际上我有大约 100.000 行而不是 3 行,这确实花费了太长时间。我一直无法弄清楚如何更有效地做到这一点,有什么想法吗?在这个例子中,我所有其他不使用索引的尝试都以矩阵 3x3 结束,因为它比较 "all with all",我认为这可能比 for.

更糟糕。

应用应该有效:

df<-data.frame(V=c("Anameone","Bnametwo","Cnamethree"),
           L=I(list(c("name","asd"),"dfg",c("hey","C","hi"))))


sapply(as.character(df$V),function(x)

{grepl(paste(unlist(df$L[1]),collapse="|"),x)})

您必须检查它是否比使用 for 循环更快。我无法重新创建您的示例。

您可以使用 purrr::map2_lgl() to iterate over both columns, testing if each element of l is in v with stringr::str_detect(),然后使用 any() 得到 TRUEFALSE 如果有任何匹配项。

library(dplyr)
library(purrr)
library(stringr)

df <- tibble(
  v = c("Anameone", "Bnametwo", "Cnamethree"),
  l = list(c("name", "asd"), "dfg", c("hey", "C", "hi"))
)

mutate(df, matches = map2_lgl(v, l, ~ str_detect(.x, .y) %>% any()))

#> # A tibble: 3 x 3
#>            v         l matches
#>        <chr>    <list>   <lgl>
#> 1   Anameone <chr [2]>    TRUE
#> 2   Bnametwo <chr [1]>   FALSE
#> 3 Cnamethree <chr [3]>    TRUE

是这样的吗?

df <- data.frame(V = c('Anameone','Bnametwo','Cnamethree'),
                 L = I(list(c('name','asd'),c('dfg'),c('hey','C','hi'))))

sapply(1:nrow(df), function(x) any(sapply(df$L[[x]], function(y) grepl(y, df$V[x]))))
# [1]  TRUE FALSE  TRUE