Grep en R con O y NO

Tengo el siguiente vector en R y me gustaría encontrar todas las cadenas que contienen a y B pero no el número 2.

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

La siguiente no funciona:

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

Me da la espalda a todas las cadenas:

[1] 1 2 3 4 5

Lo mismo es cierto para este ejemplo:

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

Lo que sería la sintaxis correcta?

  • ¿quieres partido ( A OR B ) AND NOT 2 o quieres A OR B OR (NOT 2)?

5 Kommentare

  1. 34

    Usted puede hacer esto con un simple expresión regular:

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

    En palabras, significa:

    • ^ coincide con el inicio de la cadena
    • [^2]* que coincida con cualquier cosa excepto «2», cero o más veces
    • [AB] coincide con «a» o «B»
    • [^2]* que coincida con cualquier cosa excepto «2», cero o más veces
    • $ coincidir con el final de la cadena
  2. 22

    Yo uso dos grep llamadas:

    intersect(grep("A|B",vec1),grep("2",vec1,invert=TRUE))
    #[1] 1 3
    • Genial!!! Este trabajado. Gracias de nuevo.
    • o setdiff(grep('A|B', vec1), grep('2', vec1))
  3. 18

    OP, su intento es bastante cerca, intente esto:

    grep('^(A|B|[^2])*$', vec1)
    • Este es probablemente el más compacto y sin embargo fácil de entender solución. Gracias.
    • más en general si te gusta grep('^(A|B|[^[:digit:]])*$', vec1)
    • Muy a menudo, esto producirá un resultado diferente que @Josué Ulrich’s (una de las de otros) respuesta. Así que tenga cuidado si usted aplicar esto a otro vector. Dependiendo de lo que usted está después (cf. @Anthony Damico del comentario), no podría ser lo que usted desea. Por ejemplo, grep('^(A|B|[^2])*$', "yes") devuelve 1 (después de todo, «sí», es una cadena hecha completamente de personajes que son a, B, o algunos de carácter diferente de 2). En contraste, grep("^[^2]*[AB][^2]*$", yes) devuelve integer(0), lo que parece más cerca de lo que usted desea (a diferencia de la anterior expresión, @JU s verifica la presencia de al menos un a o B).
  4. 4

    grep no suele funcionar muy bien para hacer un positivo y un negativo de búsqueda en una invocación. Usted puede ser capaz de hacer que funcione con un complejo de expresión regular, pero puede ser mejor simplemente haciendo:

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

    La R equivalente sería:

    grep("2", grep("A|B", vec1, value = T), invert = T)
    • Gracias. Lo he intentado pero no se como esta sintaxis. 🙁
  5. 0

    Me extendió la respuesta proporcionada por @eddi. Yo lo he probado en R y funciona para mí. He cambiado la última variable en su ejemplo, ya que todos los contenidos de Un|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")

    Me corrió el siguiente código. Le dirá que los resultados que puede esperar de cada sección de grep.

    Primero, me dicen que las columnas contienen Una o B

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

    Ahora dime qué columnas contienen un «2»

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

    El índice que queremos es 2,4

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

    Hecho!

Kommentieren Sie den Artikel

Bitte geben Sie Ihren Kommentar ein!
Bitte geben Sie hier Ihren Namen ein

Pruebas en línea