我有一个带分隔符的向量,我想根据其中一个分隔值是否包含我想要的内容,生成一个长度相同、具有布尔值的向量。在基于向量的逻辑中,我找不到一种巧妙地做到这一点的方法。例如:
x <- c('a', 'a; b', 'ab; c', 'b; c', 'c; a', 'c')
使用一些魔术询问%x中是否有"a"%,我想得到向量:
TRUE, TRUE, FALSE, FALSE, TRUE, FALSE
我最初尝试了以下方法:
'a' %in% trimws(strsplit(x, ';'))
但这意外地折叠了整个列表并返回TRUE,而不是向量,因为x中的一个元素是"a"。有没有一种方法可以在不将代码重写为for循环的情况下获得我正在寻找的向量?
更新:考虑空白:
library(stringr)
x <- str_replace_all(string=x, pattern=" ", repl="")
x
[1] "a" "a;b" "ab;c" "b;c" "c;a" "c"
str_detect(x, 'a$|a;')
[1] TRUE TRUE FALSE FALSE TRUE FALSE
第一个答案:如果您想使用str_detect
,我们必须考虑a
+分隔符;
:
library(stringr)
str_detect(x, 'a$|a;')
[1] TRUE TRUE FALSE FALSE TRUE FALSE
基本R:
grepl("a", x)
或者(当您想显式使用%in%时(:
sapply(strsplit(x,""), function(x){ "a" %in% x})
在处理字符串和字母时,我总是使用很棒的库stringr
library(stringr)
x <- c('a', 'a; b', 'ab; c', 'b; c', 'c; a', 'c')
str_detect(x, "a")
如果您想使用%in%
,这里有一个基本的R选项
> mapply(`%in%`, list("a"), strsplit(x, ";\s+"))
[1] TRUE TRUE FALSE FALSE TRUE FALSE
一种更有效的方法可能是使用grepl
,就像在下面一样
> grepl("\ba\b",x)
[1] TRUE TRUE FALSE FALSE TRUE FALSE
您可以使用scan
分别读取每个项目,在尝试时修剪前导和尾随WS,并依次使用测试每个生成的字符向量
sapply(x, function(x){"a" %in% trimws( scan( text=x, what="",sep=";", quiet=TRUE))})
a a; b ab; c b; c c; a c
TRUE TRUE FALSE FALSE TRUE FALSE
结果的顶行只是名称,不会影响依赖于此结果的逻辑测试。如果需要,还有一个unname
函数。