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 subpeut ê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 regexprplace de gregexpret vous pouvez ignorer le unlist.
gregexpr, regexprou les deux?
gregexpr. Je n'avais pas essayé regexprjusqu'à maintenant. Énorme différence. L'utilisation le regexprmet entre les solutions d'Andrew et d'Arun (deuxième plus rapide) sur un set 1e6. Peut-être aussi intéressant, l'utilisation subdans la solution d'Andrew n'améliore pas la vitesse.
Update
Depuis extract_numericest obsolète, nous pouvons utiliser parse_numberfrom readrpackage.
library(readr)
parse_number(years)
Voici une autre option avec extract_numeric
library(tidyr)
extract_numeric(years)
#[1] 20 1
parse_numberque 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_extractdestringr
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_allqui, contrairement à, str_extractrenvoie 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:]]+?