2013-08-14 10 views
19

Mam następujący wektor w R i chciałbym znaleźć wszystkie ciąg znaków o A i B, ale nie numer 2 w nim.Grep w R używając OR i NOT

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

Następujące nie działa:

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

Daje mi wszystkie sznurki:

[1] 1 2 3 4 5 

Tak samo jest w tym przykładzie:

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

Jaka byłaby poprawna składnia?

+2

chcesz dopasować '(A lub B) I NIE 2' czy też chcesz "A OR B OR (NIE 2)"? –

Odpowiedz

4

grep generalnie nie działa zbyt dobrze do wyszukiwania dodatniego i negatywnego w jednym wywołaniu. Możesz być w stanie, aby pracować ze złożonym wyrażeniem regularnym, ale może być lepiej po prostu robi:

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

R odpowiednikiem byłoby:

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

Dzięki. Próbowałem, ale nie podobała mi się ta składnia. :( –

20

użyłbym dwóch grep wzywa:

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

Świetnie! Ten zadziałał.Zapraszamy ponownie –

+2

lub 'setdiff (grep ('A | B', vec1), grep ('2', vec1))' – eddi

+0

Ten działał, dzięki. –

24

można to zrobić z dość prostego wyrażenia regularnego:

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

W słowy, oznacza to:

  • ^ mecz początek napisu
  • [^2]* cokolwiek mecz wyjątkiem "2" zero lub więcej razy
  • [AB] mecz "A" lub " B "
  • [^2]* pasuje do wszystkiego z wyjątkiem" 2 ", zero lub więcej razy
  • $ dopasować koniec łańcucha
14

PO, twoja próba jest dość blisko, spróbuj tego:

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

To jest prawdopodobnie najbardziej kompaktowe, a zarazem łatwe do zrozumienia rozwiązanie, dziękuję –

+0

bardziej ogólne jeśli lubisz 'grep ('^ (A | B | [^ [: cyfra:]]) * $', vec1)' – schlusie