2013-08-14 15 views
19

Ho il seguente vettore in R e vorrei trovare tutte le stringhe con A e B ma non il numero 2 in esso.Grep in R usando OR e NON

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

Quanto segue non funziona:

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

Mi restituisce tutte le stringhe:

[1] 1 2 3 4 5 

Lo stesso vale per questo esempio:

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

Quale sarebbe la sintassi corretta?

+2

vuoi abbinare '(A o B) E NON 2' o hai vuoi 'A OR B OR (NOT 2)'? –

risposta

4

grep generalmente non funziona molto bene per eseguire una ricerca positiva e negativa in una chiamata. Potreste essere in grado di farlo funzionare con un complesso espressione regolare, ma si potrebbe essere meglio solo facendo:

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

La R equivalente di ciò sarebbe:

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

Grazie. Ho provato, ma non mi piaceva questa sintassi. :( –

20

userei due grep chiamate:

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

Ottimo, questo ha funzionato Grazie ancora –

+2

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

+0

Questo ha funzionato, grazie –

24

si può fare questo con un abbastanza semplice espressione regolare:

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

In parole, significa:

  • ^ partita l'inizio della stringa
  • [^2]* partita nulla tranne "2", zero o più volte
  • [AB] partita "A" o " B "
  • [^2]* corrisponde a qualsiasi valore tranne" 2 ", zero o più volte
  • .210
  • $ corrispondere alla fine della stringa
14

OP, il tentativo è abbastanza vicino, provate questo:

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

Questo probabilmente è la soluzione più compatta e facile da capire.Grazie –

+0

più generale se ti piace 'grep ('^ (A | B | [^ [: digit:]]) * $', vec1)' – schlusie