174 votes

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 motifs de correspondance).

J'ai un cadre 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 chaînes de caractères à trouver dans les colonnes "Lettre", par exemple : c("A1", "A9", "A6") .

Je voudrais vérifier si l'une des chaînes du vecteur de motifs est présente dans la colonne "Lettre". Si c'est le cas, j'aimerais obtenir des valeurs uniques.

Le problème, c'est que je ne sais pas comment utiliser grep avec des motifs multiples. J'ai essayé :

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

Mais je n'obtiens que 0 résultat, ce qui n'est pas vrai.

329voto

Brian Diggs Points 22433

En plus du commentaire de @Marek sur le fait de ne pas inclure les fixed==TRUE Vous devez également éviter les espaces dans votre expression régulière. Elle doit être "A1|A9|A6" .

Vous mentionnez également qu'il existe de nombreux modèles. En supposant qu'ils soient dans un vecteur

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

Vous pouvez ensuite créer votre expression régulière directement à l'aide de paste y collapse = "|" .

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

44voto

Adamm Points 961

Bonnes réponses, mais n'oubliez pas 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

41voto

BOC Points 229

Cela devrait fonctionner :

grep(pattern = 'A1|A9|A6', x = myfile$Letter)

Ou plus simplement encore :

library(data.table)
myfile$Letter %like% 'A1|A9|A6'

10voto

Austin D Points 1968

Sur la base de l'article 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)
}

6voto

user3877096 Points 59

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

Exemple d'utilisation :

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

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X