我有一个由“ZZZ1Z01Z0ZZ0”,“1001ZZ0Z00Z0”等条目组成的向量,我想基于以下条件对该向量进行子集化:
我尝试使用strsplit和grep,但我无法找到根据字符串上字符位置限制条件的方法。有什么建议吗?
非常感谢!
答案 0 :(得分:10)
您可以使用正则表达式执行此操作(有关正则表达式的详细信息,请参阅?regexp
。)
grep
返回匹配的位置,如果未找到匹配则返回零长度向量。您可能希望使用grepl
,因为它返回一个可用于子集的逻辑向量。
z <- c("ZZZ1Z01Z0ZZ0", "1001ZZ0Z00Z0")
# 3rd character is Z ("^" is start of string, "." is any character)
grep("^..Z", z)
# 3rd and 7th characters are Z
grep("^..Z...Z", z)
# 3rd and 7th characters are Z, no other characters are Z
# "[]" defines a "character class" and "^" in a character class negates the match
# "{n}" repeats the preceding match n times, "+" repeats is one or more times
grep("^[^Z]{2}Z[^Z]{3}Z[^Z]+", z)
答案 1 :(得分:3)
扩展Josh的答案,你想要
your_dataset <- data.frame(
z = c("ZZZ1Z01Z0ZZ0", "1001ZZ0Z00Z0")
)
regexes <- c("^..Z", "^..Z...Z", "^[^Z]{2}Z[^Z]{3}Z[^Z]+")
lapply(regexes, function(rx)
{
subset(your_dataset, grepl(rx, z))
})
另请考虑使用grepl(rx, z)
包替换str_detect(z, rx)
stringr
。 (除了稍微更易读的代码之外没有什么区别。)
答案 2 :(得分:2)
你可以使用substr命令在没有正则表达式的情况下执行前两个,以便在需要时提取特定字符。
# Grab the third character in each element and compare it to Z
substr(z, 3, 3) == "Z"
# Check if the 3rd and 7th characters are both Z
(substr(z, 3, 3) == "Z") & (substr(z, 7, 7) == "Z")
然而,Joshua给出的正则表达式方法更灵活,并且尝试实现使用substr方法的第三个限制将是一个痛苦。正则表达式更适合于像第三个限制这样的问题,并且学习如何使用它们从来都不是一个坏主意。