我有一个由"ZZZ1Z01Z0ZZ0", "1001ZZ0Z00Z0"等条目组成的向量,我想根据以下条件对该向量进行子集提取:
- 第三个字符是 Z
- 第三个和第七个字符都是 Z
- 第三个和第七个字符都是 Z,并且没有其他字符是 Z
我尝试使用strsplit和grep,但我无法找到一种基于字符串上的字符位置限制我的条件的方法。 有什么建议吗?
非常感谢!
您可以使用正则表达式实现此目标(有关正则表达式的详细信息,请参见 ?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)
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))
})
还可以考虑使用 stringr
包中的 str_detect(z, rx)
替换 grepl(rx, z)
。这样代码不仅更易读,而且几乎没有任何区别。
# 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方法实现你所需的第三个限制时会很麻烦。正则表达式对于像第三个限制这样的问题更加适用,并学习如何使用它们永远不是一个坏主意。