R - 查找包含所有字符串/模式的所有向量元素 - str_detect grep
R - Find all vector elements that contain all strings / patterns - str_detect grep
示例数据
files.in.path = c("a.4.0. name 2015 - NY.RDS",
"b.4.0. name 2016 - CA.RDS",
"c.4.0. name 2015 - PA.RDS")
strings.to.find = c("4.0", "PA")
我想要显示包含所有 strings.to.find
的所有元素的逻辑向量。想要的结果:
FALSE FALSE TRUE
此代码将查找包含任何一个 strings.to.find
的元素,即使用 OR 运算符
str_detect(files.in.path, str_c(strings.to.find, collapse="|")) # OR operator
TRUE TRUE TRUE
此代码尝试使用 AND 运算符但不起作用。
str_detect(files.in.path, str_c(strings.to.find, collapse="&")) # AND operator
FALSE FALSE FALSE
这在几行中有效,我可以编写一个 for
循环,为具有大量 strings.to.find
的情况生成所有单独的行
det.1 = str_detect(files.in.path, "4.0" )
det.2 = str_detect(files.in.path, "PA" )
det.all = det.1 & det.2
FALSE FALSE TRUE
但是有没有更好的方法不涉及使用依赖于 strings.to.find
.
的位置或顺序的正则表达式
这不是为了繁重的工作,但是 str_detect
对字符串和模式都进行了矢量化,因此您可以将它与 outer
函数结合使用以获得接近的结果:
library(stringr)
outer(files.in.path, strings.to.find, str_detect)
# [,1] [,2]
#[1,] TRUE FALSE
#[2,] TRUE FALSE
#[3,] TRUE TRUE
要检查字符串中是否存在所有模式,apply
结果矩阵每行的 all
逻辑运算符:
apply(outer(files.in.path, strings.to.find, str_detect), 1, all)
#[1] FALSE FALSE TRUE
或者根据@Jota 的评论,如果您正在查看的模式应该完全匹配,那么在这里使用 stri_detect_fixed
会更安全:
library(stringi)
apply(outer(files.in.path, strings.to.find, stri_detect_fixed), 1, all)
# [1] FALSE FALSE TRUE
在网络上搜索 'r regex "and operaror"' 或 'regex "and operator"' 会导致 R grep: is there an AND operator?, and Regular Expressions: Is there an AND operator?分别
因此,要匹配两种模式,请将字符串连接在一起[=13=]
str <- paste0("(?=.*", strings.to.find,")", collapse="")
grepl(str, files.in.path, perl=TRUE)
正如 Jota 在评论中通过匹配“4.0”提到的那样,这也将匹配其他字符串,因为句点是一个元字符。一种解决方法是转义模式字符串中的句点,即 strings.to.find = c( "PA", "4\.0")
示例数据
files.in.path = c("a.4.0. name 2015 - NY.RDS",
"b.4.0. name 2016 - CA.RDS",
"c.4.0. name 2015 - PA.RDS")
strings.to.find = c("4.0", "PA")
我想要显示包含所有 strings.to.find
的所有元素的逻辑向量。想要的结果:
FALSE FALSE TRUE
此代码将查找包含任何一个 strings.to.find
的元素,即使用 OR 运算符
str_detect(files.in.path, str_c(strings.to.find, collapse="|")) # OR operator
TRUE TRUE TRUE
此代码尝试使用 AND 运算符但不起作用。
str_detect(files.in.path, str_c(strings.to.find, collapse="&")) # AND operator
FALSE FALSE FALSE
这在几行中有效,我可以编写一个 for
循环,为具有大量 strings.to.find
det.1 = str_detect(files.in.path, "4.0" )
det.2 = str_detect(files.in.path, "PA" )
det.all = det.1 & det.2
FALSE FALSE TRUE
但是有没有更好的方法不涉及使用依赖于 strings.to.find
.
这不是为了繁重的工作,但是 str_detect
对字符串和模式都进行了矢量化,因此您可以将它与 outer
函数结合使用以获得接近的结果:
library(stringr)
outer(files.in.path, strings.to.find, str_detect)
# [,1] [,2]
#[1,] TRUE FALSE
#[2,] TRUE FALSE
#[3,] TRUE TRUE
要检查字符串中是否存在所有模式,apply
结果矩阵每行的 all
逻辑运算符:
apply(outer(files.in.path, strings.to.find, str_detect), 1, all)
#[1] FALSE FALSE TRUE
或者根据@Jota 的评论,如果您正在查看的模式应该完全匹配,那么在这里使用 stri_detect_fixed
会更安全:
library(stringi)
apply(outer(files.in.path, strings.to.find, stri_detect_fixed), 1, all)
# [1] FALSE FALSE TRUE
在网络上搜索 'r regex "and operaror"' 或 'regex "and operator"' 会导致 R grep: is there an AND operator?, and Regular Expressions: Is there an AND operator?分别
因此,要匹配两种模式,请将字符串连接在一起[=13=]
str <- paste0("(?=.*", strings.to.find,")", collapse="")
grepl(str, files.in.path, perl=TRUE)
正如 Jota 在评论中通过匹配“4.0”提到的那样,这也将匹配其他字符串,因为句点是一个元字符。一种解决方法是转义模式字符串中的句点,即 strings.to.find = c( "PA", "4\.0")