【问题标题】:Grep in R using OR and NOT在 R 中使用 OR 和 NOT 进行 Grep
【发布时间】:2013-08-16 18:24:13
【问题描述】:

我在 R 中有以下向量,我想找到所有包含 A 和 B 但不包含数字 2 的字符串。

vec1<-c("A_cont_1", "A_cont_12", "B_treat_8", "AB_cont_22", "cont_21_Aa")

以下不起作用:

grep("A|B|!2", vec1)

它给了我所有的字符串:

[1] 1 2 3 4 5

这个例子也是如此:

grep("A|B|-2", vec1)

正确的语法是什么?

【问题讨论】:

  • 你想匹配( A OR B ) AND NOT 2还是A OR B OR (NOT 2)

标签: r regex


【解决方案1】:

grep 通常不能很好地在一次调用中进行肯定和否定搜索。您也许可以使用复杂的正则表达式使其工作,但您最好这样做:

 grep '[AB]' somefile.txt | grep -v '2'

R 等价于:

grep("2", grep("A|B", vec1, value = T), invert = T)

【讨论】:

    【解决方案2】:

    我会使用两个grep 调用:

    intersect(grep("A|B",vec1),grep("2",vec1,invert=TRUE))
    #[1] 1 3
    

    【讨论】:

    • setdiff(grep('A|B', vec1), grep('2', vec1))
    【解决方案3】:

    你可以用一个相当简单的正则表达式来做到这一点:

    grep("^[^2]*[AB][^2]*$", vec1)
    

    字面意思是:

    • ^匹配字符串的开头
    • [^2]* 匹配任何除了“2”,零次或多次
    • [AB] 匹配“A”或“B”
    • [^2]* 匹配任何除了“2”,零次或多次
    • $匹配字符串的结尾

    【讨论】:

      【解决方案4】:

      OP,你的尝试非常接近,试试这个:

      grep('^(A|B|[^2])*$', vec1)
      

      【讨论】:

      • 这可能是最紧凑且易于理解的解决方案。谢谢。
      • 如果您喜欢grep('^(A|B|[^[:digit:]])*$', vec1),则更一般
      • 很多时候,这会产生与@Joshua Ulrich(其他人)的答案不同的结果。所以如果你把它应用到另一个向量上要小心。根据您所追求的(参见@Anthony Damico 的评论),它可能不是您想要的。例如,grep('^(A|B|[^2])*$', "yes") 返回1(毕竟,“yes”是一个完全由 A、B 或不同于 2 的字符组成的字符串)。相比之下,grep("^[^2]*[AB][^2]*$", yes) 返回 integer(0),这似乎更接近您想要的(与之前的正则表达式不同,@JU 验证至少存在一个 A 或 B)。
      【解决方案5】:

      我扩展了@eddi 提供的答案。我已经在 R 中对其进行了测试,它对我有用。我更改了您示例中的最后一个变量,因为它们都包含 A|B。

      # Create the vector from the OP with one change
      vec1<-c("A_cont_1", "A_cont_12", "B_treat_8", "AB_cont_22", "cont_21_dd")
      

      然后我运行了以下代码。它将告诉您应该从 grep 的每个部分获得哪些结果。

      首先,告诉我哪些列包含 A 或 B

      > grepl("A|B", vec1)
      [1] TRUE TRUE TRUE TRUE FALSE
      

      现在告诉我哪些列包含“2”

      > grepl("2", vec1)
      [1] FALSE TRUE FALSE TRUE TRUE
      

      我们想要的索引是2,4

      > grep("2", grep("A|B", vec1, value = T))
      [1] 2 4
      

      完成!

      【讨论】:

        猜你喜欢
        • 2012-01-12
        • 2017-11-16
        • 2010-10-12
        • 1970-01-01
        • 1970-01-01
        • 2011-01-08
        • 1970-01-01
        • 1970-01-01
        • 2016-11-11
        相关资源
        最近更新 更多