web-dev-qa-db-fra.com

Grep dans R en utilisant OR et NON

J'ai le vecteur suivant dans R et je voudrais trouver toute la chaîne ayant A et B mais pas le numéro 2.

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

Ce qui suit ne fonctionne pas:

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

Cela me rend toutes les cordes:

[1] 1 2 3 4 5

La même chose est vraie pour cet exemple:

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

Quelle serait la syntaxe correcte?

25
Johnny Liseth

Vous pouvez le faire avec une expression régulière assez simple:

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

En termes, cela signifie:

  • ^ correspond au début de la chaîne
  • [^2]* ne correspond à rien sauf "2", zéro ou plusieurs fois
  • [AB] correspond à "A" ou "B"
  • [^2]* ne correspond à rien sauf "2", zéro ou plusieurs fois
  • $ correspond à la fin de la chaîne
31
Joshua Ulrich

J'utiliserais deux appels grep:

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

OP, votre tentative est assez proche, essayez ceci:

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

grep ne fonctionne généralement pas très bien pour effectuer une recherche positive et négative en une seule invocation. Vous pourrez peut-être le faire fonctionner avec une expression régulière complexe, mais vous feriez mieux de simplement faire:

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

L'équivalent R de cela serait:

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

J'ai étendu la réponse fournie par @eddi. Je l'ai testé en R et ça marche pour moi. J'ai changé la dernière variable de votre exemple car elles contenaient toutes 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")

J'ai ensuite exécuté le code suivant. Il vous dira quels résultats vous devez attendre de chaque section de grep.

Dites-moi d'abord quelles colonnes contiennent A ou B

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

Maintenant, dites-moi quelles colonnes contiennent un "2"

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

L'indice que nous voulons est de 2,4

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

Terminé!

0
Patrick