我有一个像这样的字符串:
years<-c("20 years old", "1 years old")
我想从这个向量中仅提取数字。期望的输出是一个向量:
c(20, 1)
我该怎么做呢?
怎么样?
# pattern is by finding a set of numbers in the start and capturing them
as.numeric(gsub("([0-9]+).*$", "\\1", years))
或者# pattern is to just remove _years_old
as.numeric(gsub(" years old", "", years))
或者# split by space, get the element in first index
as.numeric(sapply(strsplit(years, " "), "[[", 1))
更新
由于extract_numeric
已被弃用,我们可以使用readr
包中的parse_number
。
library(readr)
parse_number(years)
这里还有另一种选项,使用extract_numeric
library(tidyr)
extract_numeric(years)
#[1] 20 1
parse_number
不适用于负数。请尝试使用parse_number("–27,633")
。 - Nettlereadr::parse_number("-12,345") # [1] -12345
- Russ Hyde我认为替换是一种间接的获取解决方案的方法。如果您想检索所有数字,我建议使用gregexpr
:
matches <- regmatches(years, gregexpr("[[:digit:]]+", years))
as.numeric(unlist(matches))
如果一个字符串中有多个匹配项,这会获取所有匹配项。如果您只对第一个匹配项感兴趣,请使用regexpr
而不是gregexpr
,您可以跳过unlist
。
gregexpr
、regexpr
还是两者都要? - sebastian-cgregexpr
。我之前从未尝试过regexpr
,但是它的效果差别非常大。在1e6数据集上使用regexpr
可以将其排在Andrew和Arun的解决方案之间(第二快)。也许有趣的是,在Andrew的解决方案中使用sub
并不能提高速度。 - Matthew Lundberg"-?[[:digit:]]+(\\.[[:digit:]]+)?"
,我相信可以考虑到负数和小数。 - user3667133as.numeric(gsub("\\D", "", years))
# [1] 20 1
这里是对Arun第一个解决方案的替代方案,使用更简单的类Perl正则表达式:
as.numeric(gsub("[^\\d]+", "", years, perl=TRUE))
as.numeric(sub("\\D+","",years))
. If there were letters before and |or after, then gsub
- Onyambu我们也可以使用来自stringr
的str_extract
years<-c("20 years old", "1 years old")
as.integer(stringr::str_extract(years, "\\d+"))
#[1] 20 1
如果一个字符串中有多个数字,我们想要提取所有的数字,可以使用str_extract_all
。与str_extract
不同的是,它会返回所有匹配项。
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"
一个使用 stringr
管道的解决方案:
library(stringr)
years %>% str_match_all("[0-9]+") %>% unlist %>% as.numeric
as.numeric(gsub("[[:alpha:]]", "", years))
从任何字符串的开头位置提取数字。
x <- gregexpr("^[0-9]+", years) # Numbers with any number of digits
x2 <- as.numeric(unlist(regmatches(years, x)))
从字符串中提取数字,无论位置如何。
x <- gregexpr("[0-9]+", years) # Numbers with any number of digits
x2 <- as.numeric(unlist(regmatches(years, x)))
# install.packages("unglue")
library(unglue)
years<-c("20 years old", "1 years old")
unglue_vec(years, "{x} years old", convert = TRUE)
#> [1] 20 1
此内容是由reprex软件包 (v0.3.0)于2019-11-06创建的
更多信息请参见:https://github.com/moodymudskipper/unglue/blob/master/README.md
.*
?如果想要匹配字符串开头,为什么不使用^[[:digit:]]+
? - sebastian-c.*
是必要的。如果没有它,就不会删除任何内容。另外,请注意可以使用sub
来替换gsub
。 - Matthew Lundberggsub(".*?([0-9]+).*", "\\1", years)
,它可以提取 years 字符串中的第一个数字。请注意,此代码段使用的是正则表达式。 - Tomasgsub(".*?([0-9]+).*?", "\\1", "Jun. 27–30")
结果:[1] "2730"gsub(".*?([0-9]+)\\-.*?", "\\1", "Jun. 27–30")
结果:[1] "Jun. 27–30" - Lionel Trebuchon