我在数据框中有两列我想要比较的字符串。第一个是字符串向量,第二个是每个元素中带有迷你向量字符串的列表。想象一下有这样一个数据框:
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更糟糕。
答案 0 :(得分:1)
这样的东西?
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
答案 1 :(得分:0)
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循环更快。我无法再创造你的榜样。
答案 2 :(得分:0)
您可以使用purrr::map2_lgl()
对这两列进行迭代,测试l
的每个元素是否在v
中stringr::str_detect()
,然后使用any()
来如果有任何匹配,请获取TRUE
或FALSE
。
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