判断是否在字符串向量中包含指定的字符?

时间:2014-04-06 21:05:13

标签: r

strvec <- c("O.C[C@@](CC1=CC", "O[Al](O)OS",  "[Ca++]CC", "CCCCCCCCC=OOOO") 
inval.ele <- c("Al", "Ca", ".")

字符串向量为strvect,我想判断strvec是否包含inval.ele中的任何元素。如果包含,则应将其删除。

对于上面的例子,最终结果如下:

"CCCCCCCCC=OOOO"

这意味着只有这个字符串才是我想要的。

事实上,strvec的长度超过7000,inval.ele的长度超过20,处理此类问题的最有效方法是什么?

3 个答案:

答案 0 :(得分:2)

您也可以在str_detect包中尝试stringrpattern中的不同字符串可以用“|”(OR)分隔。 “.”是需要转义的特殊字符(请参阅?regex),因此是“\\”。

library(stringr)
strvec[!str_detect(string = strvec, pattern = c("Al|Ca|\\."))]
# [1] "CCCCCCCCC=OOOO"

或使用相应的base函数grepl

strvec[!grepl(x = strvec, pattern = c("Al|Ca|\\."))]
# [1] "CCCCCCCCC=OOOO"

可以使用paste

创建一系列无效元素
inval.ele <- c("Al", "Ca", "Au", "Ag", "Xe")
inval1 <- paste0(inval.ele, collapse = "|")
inval1
# [1] "Al|Ca|Au|Ag|Xe"

# add the ".", which needs to be escaped
paste(inval, "\\.", sep = "|")
# [1] "Al|Ca|Au|Ag|Xe|\\."

答案 1 :(得分:1)

grepl会扫描矢量以查找匹配项,但它只需要一个模式。要扫描多个模式,请使用for循环。

在下面的代码中,rej是要拒绝的匹配项。默认为接受(拒绝为FALSE),如果任何值匹配,则rej中的元素设置为TRUE

最后,使用!rej索引strvec

rej <- rep(FALSE, length(strvec))
for (p in inval.ele) { 
  rej <- rej | grepl(p, strvec, fixed=TRUE)
}
strvec[!rej]
## [1] "CCCCCCCCC=OOOO"

答案 2 :(得分:1)

strvec <- c("O.C[C@@](CC1=CC", "O[Al](O)OS",  "[Ca++]CC", "CCCCCCCCC=OOOO") 
inval.ele <- c("Al", "Ca", "[.]") #I've changed "." to "[.]" for gsub to recognize it

gsubfunc <- function(x, strvec){
  res <- strvec[gsub(x, "", strvec) != strvec]
}
setdiff(strvec, unique(unlist(lapply(inval.ele, gsubfunc, strvec))))
#"CCCCCCCCC=OOOO"