J'essaie d'utiliser grep
pour vérifier si un vecteur de chaînes est présent dans un autre vecteur ou non, et pour afficher les valeurs présentes (les modèles correspondants).
J'ai un cadre de données comme ceci:
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 quelconque des chaînes du vecteur de motif est présente dans la colonne "Lettre". S'ils le sont, je voudrais la sortie de valeurs uniques.
Le problème est que je ne sais pas comment utiliser grep
avec plusieurs modèles. J'ai essayé:
matches <- unique (
grep("A1| A9 | A6", myfile$Letter, value=TRUE, fixed=TRUE)
)
Mais ça me donne 0 matches ce qui n’est pas vrai, des suggestions?
Outre le commentaire de @ Marek sur le fait de ne pas inclure 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))
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
D'après le message de Brian Digg, il existe 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 motif particulier dans la question, vous pouvez simplement le faire avec un seul appel grep()
,
grep("A[169]", myfile$Letter)
Pour ajouter à Brian Diggs répondre.
autrement, 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?
Avez-vous essayé les fonctions match()
ou charmatch()
?
Exemple d'utilisation:
match(c("A1", "A9", "A6"), myfile$Letter)
Cela devrait fonctionner:
grep(pattern = 'A1|A9|A6', x = myfile$Letter)
Ou encore plus simplement:
myfile$Letter %like% 'A1|A9|A6'
Enlevez les espaces. Alors faites:
matches <- unique(grep("A1|A9|A6", myfile$Letter, value=TRUE, fixed=TRUE))
Utilisation de la 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