【问题标题】:How to subset vector based on string character?如何根据字符串字符对向量进行子集化?
【发布时间】:2011-11-23 15:45:35
【问题描述】:

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

  1. 第三个字符是 Z
  2. 第三个和第七个字符是 Z
  3. 第三个和第七个字符是 Z,其他字符都不是 Z

我尝试使用 strsplit 和 grep,但我无法找到一种方法来根据字符串上字符的位置来限制我的条件。有什么建议吗?

非常感谢!

【问题讨论】:

  • 向量是否总是具有相同的长度并且只有 0、1s 和 Z?我不知道这些东西是如何工作的,我只能给它一个正则表达式:)

标签: string r


【解决方案1】:

您可以使用正则表达式来做到这一点(有关正则表达式的详细信息,请参阅?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)

【讨论】:

  • 那你为什么还要考虑用其他方式呢?
  • 非常感谢您的帮助。我已经开始使用正则表达式,它们太棒了!不敢相信我以前没有碰到过这个。谢谢!
【解决方案2】:

扩展乔希的答案,你想要

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 包将grepl(rx, z) 替换为str_detect(z, rx)。 (除了更易读的代码外,没有真正的区别。)

【讨论】:

    【解决方案3】:

    如果需要,您可以在不使用正则表达式的情况下使用 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 方法实现第三个限制会很痛苦。正则表达式更适合解决像您的第三个限制这样的问题,学习如何使用它们绝不是一个坏主意。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-01-24
      • 2021-11-09
      • 2016-12-01
      • 1970-01-01
      • 1970-01-01
      • 2015-08-13
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多