Tengo una cadena como esta:
years<-c("20 years old", "1 years old")
Me gustaría grep solo el número numérico de este vector. La salida esperada es un vector:
c(20, 1)
¿Cómo voy a hacer esto?
Tengo una cadena como esta:
years<-c("20 years old", "1 years old")
Me gustaría grep solo el número numérico de este vector. La salida esperada es un vector:
c(20, 1)
¿Cómo voy a hacer esto?
Respuestas:
Qué tal si
# pattern is by finding a set of numbers in the start and capturing them
as.numeric(gsub("([0-9]+).*$", "\\1", years))
o
# pattern is to just remove _years_old
as.numeric(gsub(" years old", "", years))
o
# split by space, get the element in first index
as.numeric(sapply(strsplit(years, " "), "[[", 1))
.*es necesario ya que debe hacer coincidir toda la cadena. Sin eso, no se quita nada. Además, tenga en cuenta que subse puede utilizar aquí en lugar de gsub.
gsub(".*?([0-9]+).*", "\\1", years)
gsub(".*?([0-9]+).*?", "\\1", "Jun. 27–30")Resultado: [1] "2730" gsub(".*?([0-9]+)\\-.*?", "\\1", "Jun. 27–30")Resultado: [1] "27 de junio –30 "
Creo que la sustitución es una forma indirecta de llegar a la solución. Si desea recuperar todos los números, le recomiendo gregexpr:
matches <- regmatches(years, gregexpr("[[:digit:]]+", years))
as.numeric(unlist(matches))
Si tiene varias coincidencias en una cadena, esto las obtendrá todas. Si solo está interesado en la primera coincidencia, use en regexprlugar de gregexpry puede omitir el unlist.
gregexpr, regexpro ambos?
gregexpr. No lo había intentado regexprhasta ahora. Gran diferencia. Usar lo regexprcoloca entre las soluciones de Andrew y Arun (el segundo más rápido) en un set de 1e6. Quizás también sea interesante, usar suben la solución de Andrew no mejora la velocidad.
Actualización
Dado que extract_numericestá en desuso, podemos usar parse_numberfrom readrpackage.
library(readr)
parse_number(years)
Aquí hay otra opción con extract_numeric
library(tidyr)
extract_numeric(years)
#[1] 20 1
parse_numberque no se juega con números negativos. Try parse_number("–27,633")
readr::parse_number("-12,345") # [1] -12345
También podrías deshacerte de todas las letras:
as.numeric(gsub("[[:alpha:]]", "", years))
Sin embargo, es probable que esto sea menos generalizable.
Extrae números de cualquier cadena en la posición inicial.
x <- gregexpr("^[0-9]+", years) # Numbers with any number of digits
x2 <- as.numeric(unlist(regmatches(years, x)))
Extrae números de cualquier cadena INDEPENDIENTE de la posición.
x <- gregexpr("[0-9]+", years) # Numbers with any number of digits
x2 <- as.numeric(unlist(regmatches(years, x)))
También podemos utilizar str_extractdesdestringr
years<-c("20 years old", "1 years old")
as.integer(stringr::str_extract(years, "\\d+"))
#[1] 20 1
Si hay varios números en la cadena y queremos extraerlos todos, podemos usar str_extract_allque, a diferencia de, str_extractdevuelve todos los 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"
Después de la publicación de Gabor Grothendieck en la lista de correo de 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]])
Usando el paquete unglue podemos hacer:
# install.packages("unglue")
library(unglue)
years<-c("20 years old", "1 years old")
unglue_vec(years, "{x} years old", convert = TRUE)
#> [1] 20 1
Creado el 2019-11-06 por el paquete reprex reprex (v0.3.0)
Más información: https://github.com/moodymudskipper/unglue/blob/master/README.md
.*necesario? Si los quiere al principio, ¿por qué no usarlos^[[:digit:]]+?