1
votes

correspondance de chaîne: mots + caractères

J'essaie de rechercher un dataframe pour correspondre à une chaîne, où j'ai créé un objet à partir d'une colonne remplie de notes.

À titre d'exemple:

Je recherche une ligne avec notes qui pourraient correspondre

> mph_words %in% lc_notes[2000]
[1] FALSE FALSE FALSE FALSE

> pmatch(mph_words, lc_notes[1703])
[1] NA NA NA NA

grepl(lc_notes[1703],mph_words)
[1] FALSE FALSE FALSE FALSE

> str_detect(mph_words,lc_notes[1703])
[1] FALSE FALSE FALSE FALSE

> for (word in 1:length(mph_words)){
+   print(str_extract(mph_words[word],lc_notes[1703]))
+ }
[1] NA
[1] NA
[1] NA
[1] NA

Et une ligne de code peut ressembler à:

> lc_notes[1703]
[1] "collected 1.667 man-hr total. mostly cloudy, windy with gusts >20 mph."

Comme vous pouvez le voir, certains des les notes ont des espaces entre "" et le nombre donc utiliser strsplit pour rechercher ne serait pas idéal car j'ai besoin de garder le "" avec le nombre.

J'ai essayé

mph_words<-c(">10", "> 10", ">20", "> 20")

et je ne sais pas quoi essayer ensuite. Si c'est une expression regex, pourriez-vous simplement l'expliquer dans votre réponse? J'essaye de mieux comprendre les regex.

Modifier J'essaie d'imprimer des lignes qui ont spécifiquement l'un des caractères de mph_words. Ainsi, le code rechercherait chaque ligne de mes lc_notes et imprimerait la ligne 1703.

Merci d'avance!


2 commentaires

Merci à tous pour l'aide rapide et surtout, l'explication du code! @ G5W - merci pour toutes les modifications, mais garder le # était important car la valeur de mph compte pour la partie suivante du code.


@nate merci! J'aurais dû mieux clarifier (toujours en train d'apprendre à poser des questions) mais lc_notes avait des espaces ambigus entre ">" / "<", c'est pourquoi j'essayais d'écrire différentes façons de rendre compte de cela dans mph_words


3 Réponses :


3
votes

Modifié pour correspondre à la question modifiée:
Pour trouver les numéros de ligne, utilisez grep

grep("[<>]\\s*\\d+\\b",  lc_notes)

[] correspond à
\\ s * autorise les espaces blancs facultatifs
\\ d correspond aux nombres suivants.

grep donnera les numéros des lignes qui correspondent.


4 commentaires

J'ai juste essayé de copier + coller votre code mais j'ai obtenu ceci:> sub (". * ([<>] \ S * \ d + \ b). *", "\\ 1", lc_notes) Erreur: '\ s' est un échappement non reconnu dans la chaîne de caractères commençant par "". * ([<>] \ s "pourriez-vous expliquer votre code? Merci!


Voici l'erreur que j'ai obtenue: Erreur: '\ s' est un échappement non reconnu dans la chaîne de caractères commençant par "". * ([<>] \ S "


Corrige ça maintenant. Essayez la nouvelle version.


Merci! J'ai une impression mais je clarifie ma question. Merci pour l'explication regex - c'était TRÈS utile



1
votes

Voici un moyen d'utiliser strsplit et lapply

mph_words <- c(">10", "> 10", ">20", "> 20")  
lc_notes <- "collected 1.667 man-hr total. mostly cloudy, windy with gusts >20 mph."
lc_notes <- c(lc_notes, 'test >10', '>15')

avec les données

# standardize (get rid of white spaces between <,> and digits in mph_words
mph_words <- unique(gsub('([<>])\\s{0,}(\\d+)', '\\1\\2', mph_words, perl = TRUE))        
# match 
check <- lapply(1:length(lc_notes), 
                function (k) any(mph_words %in% unlist(strsplit(lc_notes[k], ' '))))
check
# [[1]]
# [1] TRUE

# [[2]]
# [1] TRUE

# [[3]]
# [1] FALSE

# Finally printing the indices with a match
which(unlist(check))
# [1] 1 2


0 commentaires

2
votes

J'utiliserais apply avec stringr :: str_detect pour cela:

mph_words<-c("> ?10", "> ?20")

sapply bouclera à travers chaque élément du vecteur lc_notes , en appliquant le test à chacun. Ensuite, en utilisant any , nous simplifions le vecteur à une seule valeur logique.

Si vous voulez les numéros de ligne, plutôt qu'un vecteur logique, utilisez le qui code> fonction:

names(which(sapply(lc_notes, function(x) any(str_detect(x, mph_words)))))
[1] "collected 1.667 man-hr total. mostly cloudy, windy with gusts >20 mph." 
[2] "collected 1.667 man-hr total. mostly cloudy, windy with gusts > 20 mph."

J'ai utilisé unname ici pour mettre en évidence que le vecteur renvoyé est l'index des éléments dans lc_notes code> qui correspondent à l'un des modèles de regex. Vous pouvez également faire l'inverse et appeler des noms dessus pour obtenir le texte de la ligne:

unname(which(sapply(lc_notes, function(x) any(str_detect(x, mph_words)))))
[1] 1 2

Si vous voulez un plus simple regex, qui correspond avec ou sans espaces, utilisez le quantificateur facultatif ? sur le caractère d'espace:

lc_notes <- c("collected 1.667 man-hr total. mostly cloudy, windy with gusts >20 mph.",
              "collected 1.667 man-hr total. mostly cloudy, windy with gusts > 20 mph.",
              "collected 1.667 man-hr total. mostly cloudy, windy with gusts of 20 mph.")
mph_words<-c(">10", "> 10", ">20", "> 20")

sapply(lc_notes, function(x) any(str_detect(x, mph_words)))

collected 1.667 man-hr total. mostly cloudy, windy with gusts >20 mph. 
                                                                    TRUE 
collected 1.667 man-hr total. mostly cloudy, windy with gusts > 20 mph. 
                                                                    TRUE 
collected 1.667 man-hr total. mostly cloudy, windy with gusts of 20 mph. 
                                                                   FALSE 


1 commentaires

Merci! C'est exactement ce que j'espérais! J'apprécie vraiment le? option, en particulier l'option names / unname!