web-dev-qa-db-fra.com

Extraire des nombres à partir de vecteurs de chaînes

J'ai ficelle comme ceci:

years<-c("20 years old", "1 years old")

Je voudrais grep seulement le nombre numérique de ce vecteur. La sortie attendue est un vecteur:

c(20, 1)

Comment puis-je faire cela?

76
user1471980

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))
67
Arun

Je pense que la substitution est un moyen indirect de parvenir à la solution. Si vous voulez 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, toutes les obtiendront. Si vous ne vous intéressez qu'à la première correspondance, utilisez regexpr au lieu de gregexpr et vous pouvez ignorer le unlist.

48
sebastian-c

Mise à jour Depuis extract_numeric est obsolète, on peut utiliser parse_number de readr paquet.

library(readr)
parse_number(years)

Voici une autre option avec extract_numeric

library(tidyr)
extract_numeric(years)
#[1] 20  1
43
akrun

Voici une alternative à la première solution d'Arun, avec une expression rationnelle plus simple ressemblant à Perl:

as.numeric(gsub("[^\\d]+", "", years, Perl=TRUE))
30
Andrew

Ou simplement:

as.numeric(gsub("\\D", "", years))
# [1] 20  1
19
989

Une solution stringr en pipeline:

library(stringr)
years %>% str_match_all("[0-9]+") %>% unlist %>% as.numeric
15
Joe

Vous pouvez aussi vous débarrasser de toutes les lettres:

as.numeric(gsub("[[:alpha:]]", "", years))

Cela est probablement moins généralisable cependant.

15
Tyler Rinker

Extrait des nombres de n'importe quelle chaîne à la position de départ.

x <- gregexpr("^[0-9]+", years)  # Numbers with any number of digits
x2 <- as.numeric(unlist(regmatches(years, x)))

Extraire les nombres de toute chaîne indépendante de la position.

x <- gregexpr("[0-9]+", years)  # Numbers with any number of digits
x2 <- as.numeric(unlist(regmatches(years, x)))
4
sbaniwal

Après la publication de Gabor Grothendieck publication 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]])
2
juanbretti

Nous pouvons aussi utiliser str_extract de stringr

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 retourne 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"
0
Ronak Shah