Ich habe eine Zeichenfolge wie diese:
years<-c("20 years old", "1 years old")
Ich möchte nur die numerische Zahl aus diesem Vektor erfassen. Die erwartete Ausgabe ist ein Vektor:
c(20, 1)
Wie mache ich das?
Ich habe eine Zeichenfolge wie diese:
years<-c("20 years old", "1 years old")
Ich möchte nur die numerische Zahl aus diesem Vektor erfassen. Die erwartete Ausgabe ist ein Vektor:
c(20, 1)
Wie mache ich das?
Antworten:
Wie wäre es mit
# pattern is by finding a set of numbers in the start and capturing them
as.numeric(gsub("([0-9]+).*$", "\\1", years))
oder
# pattern is to just remove _years_old
as.numeric(gsub(" years old", "", years))
oder
# split by space, get the element in first index
as.numeric(sapply(strsplit(years, " "), "[[", 1))
.*
ist erforderlich, da Sie die gesamte Zeichenfolge abgleichen müssen. Ohne das wird nichts entfernt. Beachten Sie auch, dass sub
hier anstelle von verwendet werden kann gsub
.
gsub(".*?([0-9]+).*", "\\1", years)
gsub(".*?([0-9]+).*?", "\\1", "Jun. 27–30")
Ergebnis: [1] "2730" gsub(".*?([0-9]+)\\-.*?", "\\1", "Jun. 27–30")
Ergebnis: [1] "27. Juni –30 "
Ich denke, dass Substitution ein indirekter Weg ist, um zur Lösung zu gelangen. Wenn Sie alle Nummern abrufen möchten, empfehle ich gregexpr
:
matches <- regmatches(years, gregexpr("[[:digit:]]+", years))
as.numeric(unlist(matches))
Wenn Sie mehrere Übereinstimmungen in einer Zeichenfolge haben, werden alle diese erhalten. Wenn Sie nur am ersten Spiel interessiert sind, verwenden Sie regexpr
stattdessen gregexpr
und Sie können das überspringen unlist
.
gregexpr
, regexpr
oder beides?
gregexpr
. Ich hatte es regexpr
bis jetzt nicht versucht . RIESIGER Unterschied. Mit regexpr
setzt es zwischen Andrews und Aruns Lösungen (zweitschnellste) auf einem 1e6-Set. Vielleicht auch interessant, die Verwendung sub
in Andrews Lösung verbessert die Geschwindigkeit nicht.
Update
Da extract_numeric
veraltet ist, können wir parse_number
aus readr
Paket verwenden.
library(readr)
parse_number(years)
Hier ist eine weitere Option mit extract_numeric
library(tidyr)
extract_numeric(years)
#[1] 20 1
parse_number
spielt nicht mit negativen Zahlen. Versuchen Sie parse_number("–27,633")
readr::parse_number("-12,345") # [1] -12345
Sie könnten auch alle Buchstaben loswerden:
as.numeric(gsub("[[:alpha:]]", "", years))
Wahrscheinlich ist dies jedoch weniger verallgemeinerbar.
Extrahieren Sie Zahlen aus einer beliebigen Zeichenfolge an der Anfangsposition.
x <- gregexpr("^[0-9]+", years) # Numbers with any number of digits
x2 <- as.numeric(unlist(regmatches(years, x)))
Extrahieren Sie Zahlen aus einer beliebigen Zeichenfolge, die von der Position UNABHÄNGIG ist.
x <- gregexpr("[0-9]+", years) # Numbers with any number of digits
x2 <- as.numeric(unlist(regmatches(years, x)))
Wir können auch str_extract
von verwendenstringr
years<-c("20 years old", "1 years old")
as.integer(stringr::str_extract(years, "\\d+"))
#[1] 20 1
Wenn die Zeichenfolge mehrere Zahlen enthält und wir alle extrahieren möchten, können wir verwenden, str_extract_all
die im Gegensatz zu str_extract
allen Zahlen alle Macthes zurückgeben.
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"
Nach dem Beitrag von Gabor Grothendieck auf der R-Hilfe-Mailingliste
years<-c("20 years old", "1 years old")
library(gsubfn)
pat <- "[-+.e0-9]*\\d"
sapply(years, function(x) strapply(x, pat, as.numeric)[[1]])
Mit dem Paket Kleber können wir Folgendes tun:
# install.packages("unglue")
library(unglue)
years<-c("20 years old", "1 years old")
unglue_vec(years, "{x} years old", convert = TRUE)
#> [1] 20 1
Erstellt am 06.11.2019 durch das reprex-Paket (v0.3.0)
Weitere Informationen: https://github.com/moodymudskipper/unglue/blob/master/README.md
.*
notwendig? Wenn Sie sie am Anfang haben möchten, warum nicht verwenden^[[:digit:]]+
?