web-dev-qa-db-ja.com

OR and NOTを使用したRのGrep

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)

正しい構文は何でしょうか?

25
Johnny Liseth

これは、かなり単純な正規表現を使用して実行できます。

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

言葉で、それは意味します:

  • ^文字列の先頭に一致
  • [^2]*何にでも一致除く "2"、ゼロ回以上
  • [AB]「A」または「B」に一致
  • [^2]*何にでも一致除く "2"、ゼロ回以上
  • $文字列の末尾に一致
31
Joshua Ulrich

2つのgrep呼び出しを使用します。

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

OP、あなたの試みはかなり近いです、これを試してください:

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

grepは、通常、1回の呼び出しでポジティブ検索とネガティブ検索を行う場合にはあまりうまく機能しません。複雑な正規表現で機能させることができるかもしれませんが、次のようにするだけの方が良いかもしれません。

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

それに相当するRは次のようになります。

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

@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

できた!

0
Patrick