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 sub
se 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 regexpr
lugar de gregexpr
y puede omitir el unlist
.
gregexpr
, regexpr
o ambos?
gregexpr
. No lo había intentado regexpr
hasta ahora. Gran diferencia. Usar lo regexpr
coloca 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 sub
en la solución de Andrew no mejora la velocidad.
Actualización
Dado que extract_numeric
está en desuso, podemos usar parse_number
from readr
package.
library(readr)
parse_number(years)
Aquí hay otra opción con extract_numeric
library(tidyr)
extract_numeric(years)
#[1] 20 1
parse_number
que 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_extract
desdestringr
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_all
que, a diferencia de, str_extract
devuelve 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:]]+
?