grep utilisant un vecteur de caractères avec plusieurs motifs

J’essaie d’utiliser grep pour tester si un vecteur de chaînes est présent ou non dans un autre vecteur, et pour afficher les valeurs présentes (les modèles correspondants).

J’ai un bloc de données comme celui-ci:

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

J’ai un vecteur de motifs de chaînes à trouver dans les colonnes “Lettre”, par exemple: c("A1", "A9", "A6") .

Je voudrais vérifier si l’une des chaînes du vecteur de motif est présente dans la colonne “Lettre”. Si tel est le cas, je voudrais la sortie de valeurs uniques.

Le problème est que je ne sais pas comment utiliser grep avec plusieurs motifs. J’ai essayé:

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

Mais cela me donne 0 correspondances ce qui n’est pas vrai, des suggestions?

En plus du commentaire de @ Marek sur l’inclusion de fixed==TRUE , vous devez également ne pas avoir les espaces dans votre expression régulière. Ce devrait être "A1|A9|A6" .

Vous mentionnez également qu’il y a beaucoup de modèles. En supposant qu’ils sont dans un vecteur

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

Ensuite, vous pouvez créer votre expression régulière directement à partir de cela.

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

De bonnes réponses, mais n’oubliez pas de 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 

Basé sur le post de Brian Digg, voici deux fonctions utiles pour filtrer les listes:

 #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) } 

Pas sûr que cette réponse soit déjà apparue …

Pour le modèle particulier de la question, vous pouvez le faire avec un seul appel grep() ,

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

Avez-vous essayé les fonctions match() ou charmatch() ?

Exemple d’utilisation:

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

Pour append à Brian Diggs, répondez.

Une autre manière d’utiliser grepl renverra un bloc de données contenant toutes vos valeurs.

 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 

Peut-être un peu plus propre ... peut-être?

Enlevez les espaces. Alors faites:

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

Utiliser le 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 

Je suggère d’écrire un petit script et de faire plusieurs recherches avec Grep. Je n’ai jamais trouvé un moyen de rechercher plusieurs modèles, et croyez-moi, j’ai regardé!

Comme ça, votre fichier shell, avec une chaîne intégrée:

  #!/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"; 

Puis lancez en tapant myshell.sh.

Si vous voulez pouvoir passer la chaîne sur la ligne de commande, faites-le comme ça, avec un argument shell – c’est la notation bash btw:

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

Et ainsi de suite.

S’il y a beaucoup de motifs à assortir, vous pouvez le mettre dans une boucle for.

Coller une regex semble beaucoup de travail. Je suis d’accord avec David Arenburg; Si vous savez exactement ce que vous voulez, indiquez simplement votre trame de données.

 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 

Créé le 2018-08-16 par le package reprex (v0.2.0).