R 在另一个向量的元素中查找向量的字符串模式(成对)

R finding string patterns of a vector in elements of another (by pairs)

提问人:jeanlain 提问时间:10/14/2016 最后编辑:oguz ismailjeanlain 更新时间:8/6/2020 访问量:1357

问:

我有一个字符向量

c1 <- c("BEL","BEL","BEL","BEL")

和另一个相同长度的字符向量

c2 <- c(" BEL-65_DRe-I_1p:BEL;_LTR_Retrotransposon;_Transposable_Element;_Nonautonomous;_BEL-65_DRe-I", "L1-2_NN_3p:L1;_Non-LTR_Retrotransposon;_Transposable_Element;_L1-2_NN", "BEL-13_CQ-I_1p:BEL;_LTR_Retrotransposon;_Transposable_Element;_BEL-13_CQ_;_BEL-13_CQ-LTR;_BEL-13_CQ-I", "BEL-31_CQ-I_1p:BEL;_LTR_Retrotransposon;_Transposable_Element;_BEL-31_CQ_;_BEL-31_CQ-LTR;_BEL-31_CQ-I", "Gypsy-22_CQ-I_1p:Gypsy;_LTR_Retrotransposon;_Transposable_Element;_Gypsy-22_CQ_;_Gypsy-22_CQ-LTR;_Gypsy-22_CQ-I")

我想知道是否在同一个索引中找到每个字符串(忽略大小写),即是否在、在等中找到。 在实践中,向量可以有数百万个元素。c1c2c1[1]c2[1]c1[2]c2[2]

我目前的解决方案是

test <- Map(function(x,y) grepl(x,y, ignore.case = T), c1, c2)

但它没有矢量化,因此相对较慢。 有没有更好的解决方案?

R 向量

评论

0赞 lukeA 10/14/2016
你试过吗?library(stringi);c1 <- stri_rand_strings(1e6, 2);c2 <- paste0(stri_rand_strings(1e6, 20), tolower(c1));system.time(res <- stri_detect(c2, fixed = c1, case_insensitive = TRUE))
0赞 jeanlain 10/14/2016
谢谢!我知道必须有一个专门的功能。我什至已经安装了 stringi,但其中的功能太多了,很难找到您需要的功能。你可以发布这个答案,以便我验证它。
0赞 lukeA 10/14/2016
当然,只是这样做了。

答:

1赞 Benjamin Mohn 10/14/2016 #1

什么也行得通,因为你的解决方案是使用 . 对于这个小例子,它运行良好,对于更大的数据是否会更快,我不知道。apply

apply(rbind(c1,c2), 2, function(y){grepl(pattern = y[1],x=y[2], ignore.case = T)})
[1]  TRUE FALSE  TRUE  TRUE FALSE 

编辑: 我不得不再添加一个“BEL”才能使其工作,因为您的 c1 由 4 个元素组成,而 c2 由 5 个元素组成

评论

0赞 jeanlain 10/14/2016
谢谢,我认为它应该可以正常工作,因为它们在内部都依赖于循环。Map()for
3赞 User2321 10/14/2016 #2

您可以使用 stringr 包尝试以下操作:

require(stringr)
require(data.table)

data <- data.table(c1, c2)
data[, FOUND:= str_detect(toupper(c2), toupper(c1))]

评论

0赞 jeanlain 10/14/2016
谢谢,它应该和解决方案一样好用。stringi
0赞 User2321 10/14/2016
是的,我认为大致相同。
4赞 lukeA 10/14/2016 #3

这运行得非常快:

library(stringi)
c1 <- stri_rand_strings(1e6, 2)
c2 <- paste0(stri_rand_strings(1e6, 20), tolower(c1))
system.time(res <- stri_detect(c2, fixed = c1, case_insensitive = TRUE))
       # User      System verstrichen 
       # 0.73        0.00        0.75

部分原因是因为我没有检查正则表达式模式,而是检查常量字符串 (),您也可以在 中使用它。fixedgrep*