grep usando un vector de caracteres con múltiples patrones

Estoy tratando de usar grep para probar si un vector de cadenas está presente en otro vector o no, y para generar los valores que están presentes (los patrones coincidentes).

Tengo un dataframe como este:

 FirstName Letter Alex A1 Alex A6 Alex A7 Bob A1 Chris A9 Chris A6 

Tengo un vector de patrones de cadenas que se encuentran en las columnas “Carta”, por ejemplo: c("A1", "A9", "A6") .

Me gustaría comprobar si alguna de las cadenas en el vector de patrones está presente en la columna “Carta”. Si lo son, me gustaría el resultado de valores únicos.

El problema es que no sé cómo usar grep con múltiples patrones. Lo intenté:

 matches <- unique ( grep("A1| A9 | A6", myfile$Letter, value=TRUE, fixed=TRUE) ) 

Pero me da 0 coincidencias que no es cierto, ¿alguna sugerencia?

Además del comentario de @ Marek sobre no incluir fixed==TRUE , tampoco es necesario que tenga los espacios en su expresión regular. Debería ser "A1|A9|A6" .

También mencionas que hay muchos patrones. Suponiendo que están en un vector

 toMatch < - c("A1", "A9", "A6") 

Luego puedes crear tu expresión regular directamente a partir de esto.

 matches < - unique (grep(paste(toMatch,collapse="|"), myfile$Letter, value=TRUE)) 

Buenas respuestas, sin embargo, no olvide el filter() de dplyr:

 patterns < - c("A1", "A9", "A6") >your_df FirstName Letter 1 Alex A1 2 Alex A6 3 Alex A7 4 Bob A1 5 Chris A9 6 Chris A6 result < - filter(your_df, grepl(paste(patterns, collapse="|"), Letter)) >result FirstName Letter 1 Alex A1 2 Alex A6 3 Bob A1 4 Chris A9 5 Chris A6 

Basado en la publicación de Brian Digg, aquí hay dos funciones útiles para filtrar listas:

 #Returns all items in a list that are not contained in toMatch #toMatch can be a single item or a list of items exclude < - function (theList, toMatch){ return(setdiff(theList,include(theList,toMatch))) } #Returns all items in a list that ARE contained in toMatch #toMatch can be a single item or a list of items include <- function (theList, toMatch){ matches <- unique (grep(paste(toMatch,collapse="|"), theList, value=TRUE)) return(matches) } 

No estoy seguro de si esta respuesta ya apareció …

Para el patrón particular en la pregunta, puede hacerlo con una sola llamada grep() ,

 grep("A[169]", myfile$Letter) 

¿Has probado las funciones match() o charmatch() ?

Ejemplo de uso:

 match(c("A1", "A9", "A6"), myfile$Letter) 

Para agregar a la respuesta de Brian Diggs.

Otra forma de usar grepl devolverá un dataframe que contiene todos sus valores.

 toMatch < - myfile$Letter matches <- myfile[grepl(paste(toMatch, collapse="|"), myfile$Letter), ] matches Letter Firstname 1 A1 Alex 2 A6 Alex 4 A1 Bob 5 A9 Chris 6 A6 Chris 

Tal vez un poco más limpio ... tal vez?

Quita los espacios. Entonces hazlo

 matches < - unique(grep("A1|A9|A6", myfile$Letter, value=TRUE, fixed=TRUE)) 

Usando el sapply

  patterns < - c("A1", "A9", "A6") df <- data.frame(name=c("A","Ale","Al","lex","x"),Letters=c("A1","A2","A9","A1","A9")) name Letters 1 A A1 2 Ale A2 3 Al A9 4 lex A1 5 x A9 df[unlist(sapply(patterns, grep, df$Letters, USE.NAMES = F)), ] name Letters 1 A A1 4 lex A1 3 Al A9 5 x A9 

Sugiero escribir un pequeño guión y hacer búsquedas múltiples con Grep. Nunca he encontrado una manera de buscar patrones múltiples, y créanme, ¡lo he buscado!

Al igual que su archivo de shell, con una cadena incrustada:

  #!/bin/bash grep *A6* "Alex A1 Alex A6 Alex A7 Bob A1 Chris A9 Chris A6"; grep *A7* "Alex A1 Alex A6 Alex A7 Bob A1 Chris A9 Chris A6"; grep *A8* "Alex A1 Alex A6 Alex A7 Bob A1 Chris A9 Chris A6"; 

Luego ejecute escribiendo myshell.sh.

Si desea poder pasar la cadena en la línea de comando, hágalo así, con un argumento de shell; esto es notación bash por cierto:

  #!/bin/bash $stingtomatch = "${1}"; grep *A6* "${stingtomatch}"; grep *A7* "${stingtomatch}"; grep *A8* "${stingtomatch}"; 

Etcétera.

Si hay muchos patrones para combinar, puede ponerlo en un ciclo for.

Pegar juntos una expresión regular parece mucho trabajo. Estoy de acuerdo con David Arenburg; si sabe exactamente lo que quiere, simplemente dígale a su dataframe.

 library(tidyverse) # Data myfile < -read.table(text = "FirstName Letter Alex A1 Alex A6 Alex A7 Bob A1 Chris A9 Chris A6", header = T) patterns <- c("A1","A9","A6") myfile %>% filter(Letter %in% patterns) #> FirstName Letter #> 1 Alex A1 #> 2 Alex A6 #> 3 Bob A1 #> 4 Chris A9 #> 5 Chris A6 

Creado en 2018-08-16 por el paquete reprex (v0.2.0).