如何基于字符串字符子集矢量?

时间:2011-11-23 15:45:36

标签: string r

我有一个由“ZZZ1Z01Z0ZZ0”,“1001ZZ0Z00Z0”等条目组成的向量,我想基于以下条件对该向量进行子集化:

  1. 第三个字符是Z
  2. 第三个和第七个字符是Z
  3. 第三个和第七个字符是Z,并且其他字符都不是Z
  4. 我尝试使用strsplit和grep,但我无法找到根据字符串上字符位置限制条件的方法。有什么建议吗?

    非常感谢!

3 个答案:

答案 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方法的第三个限制将是一个痛苦。正则表达式更适合于像第三个限制这样的问题,并且学习如何使用它们从来都不是一个坏主意。