J'ai une chaîne comme celle-ci:
years<-c("20 years old", "1 years old")
Je voudrais grep uniquement le nombre numérique de ce vecteur. La sortie attendue est un vecteur:
c(20, 1)
Comment dois-je procéder?
J'ai une chaîne comme celle-ci:
years<-c("20 years old", "1 years old")
Je voudrais grep uniquement le nombre numérique de ce vecteur. La sortie attendue est un vecteur:
c(20, 1)
Comment dois-je procéder?
Réponses:
Que diriez-vous
# pattern is by finding a set of numbers in the start and capturing them
as.numeric(gsub("([0-9]+).*$", "\\1", years))
ou
# pattern is to just remove _years_old
as.numeric(gsub(" years old", "", years))
ou
# split by space, get the element in first index
as.numeric(sapply(strsplit(years, " "), "[[", 1))
.*
est nécessaire car vous devez faire correspondre la chaîne entière. Sans cela, rien n'est supprimé. Notez également que cela sub
peut être utilisé ici à la place de gsub
.
gsub(".*?([0-9]+).*", "\\1", years)
gsub(".*?([0-9]+).*?", "\\1", "Jun. 27–30")
Résultat: [1] "2730" gsub(".*?([0-9]+)\\-.*?", "\\1", "Jun. 27–30")
Résultat: [1] "27 juin –30 "
Je pense que la substitution est un moyen indirect d'arriver à la solution. Si vous souhaitez récupérer tous les numéros, je vous recommande gregexpr
:
matches <- regmatches(years, gregexpr("[[:digit:]]+", years))
as.numeric(unlist(matches))
Si vous avez plusieurs correspondances dans une chaîne, cela les obtiendra toutes. Si vous n'êtes intéressé que par le premier match, utilisez à la regexpr
place de gregexpr
et vous pouvez ignorer le unlist
.
gregexpr
, regexpr
ou les deux?
gregexpr
. Je n'avais pas essayé regexpr
jusqu'à maintenant. Énorme différence. L'utilisation le regexpr
met entre les solutions d'Andrew et d'Arun (deuxième plus rapide) sur un set 1e6. Peut-être aussi intéressant, l'utilisation sub
dans la solution d'Andrew n'améliore pas la vitesse.
Update
Depuis extract_numeric
est obsolète, nous pouvons utiliser parse_number
from readr
package.
library(readr)
parse_number(years)
Voici une autre option avec extract_numeric
library(tidyr)
extract_numeric(years)
#[1] 20 1
parse_number
que ne joue pas avec des nombres négatifs. Essayer parse_number("–27,633")
readr::parse_number("-12,345") # [1] -12345
Vous pouvez également vous débarrasser de toutes les lettres:
as.numeric(gsub("[[:alpha:]]", "", years))
Cela est probablement moins généralisable.
Extrayez les nombres de n'importe quelle chaîne à la position de début.
x <- gregexpr("^[0-9]+", years) # Numbers with any number of digits
x2 <- as.numeric(unlist(regmatches(years, x)))
Extraire les nombres de n'importe quelle chaîne INDÉPENDANTE de position.
x <- gregexpr("[0-9]+", years) # Numbers with any number of digits
x2 <- as.numeric(unlist(regmatches(years, x)))
Nous pouvons également utiliser str_extract
destringr
years<-c("20 years old", "1 years old")
as.integer(stringr::str_extract(years, "\\d+"))
#[1] 20 1
S'il y a plusieurs nombres dans la chaîne et que nous voulons tous les extraire, nous pouvons utiliser str_extract_all
qui, contrairement à, str_extract
renvoie tous les macthes.
years<-c("20 years old and 21", "1 years old")
stringr::str_extract(years, "\\d+")
#[1] "20" "1"
stringr::str_extract_all(years, "\\d+")
#[[1]]
#[1] "20" "21"
#[[2]]
#[1] "1"
Après le message de Gabor Grothendieck, postez sur la liste de diffusion r-help
years<-c("20 years old", "1 years old")
library(gsubfn)
pat <- "[-+.e0-9]*\\d"
sapply(years, function(x) strapply(x, pat, as.numeric)[[1]])
En utilisant le package unglue, nous pouvons faire:
# install.packages("unglue")
library(unglue)
years<-c("20 years old", "1 years old")
unglue_vec(years, "{x} years old", convert = TRUE)
#> [1] 20 1
Créé le 06/11/2019 par le package reprex (v0.3.0)
Plus d'infos: https://github.com/moodymudskipper/unglue/blob/master/README.md
.*
nécessaire? Si vous les voulez au départ, pourquoi ne pas les utiliser^[[:digit:]]+
?