문자열 벡터에서 숫자 추출


102

다음과 같은 문자열이 있습니다.

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

이 벡터의 숫자 만 grep하고 싶습니다. 예상 출력은 벡터입니다.

c(20, 1)

어떻게해야합니까?

답변:


86

어때

# 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))

1
.*필요한가요? 처음에 원하는 경우 사용하지 않는 이유는 ^[[:digit:]]+무엇입니까?
sebastian-c 2013

2
.*전체 문자열과 일치해야하므로 필요합니다. 그것 없이는 아무것도 제거되지 않습니다. 또한 sub여기에서 대신 사용할 수 있습니다 gsub.
Matthew Lundberg 2013 년

13
숫자가 문자열의 시작 부분에있을 필요가없는 경우 다음을 사용하십시오.gsub(".*?([0-9]+).*", "\\1", years)
TMS

27을 얻고 싶습니다. 조건을 추가하여 (예 : 이스케이프 "-"를 추가하면 결과가 더 길어집니다 ... gsub(".*?([0-9]+).*?", "\\1", "Jun. 27–30")결과 : [1] "2730" gsub(".*?([0-9]+)\\-.*?", "\\1", "Jun. 27–30")결과 : [1] "Jun. 27 –30 "
Lionel Trebuchon 19.06.05

66

나는 대체가 해결책을 얻는 간접적 인 방법이라고 생각합니다. 모든 번호를 검색하려면 gregexpr다음을 권장합니다 .

matches <- regmatches(years, gregexpr("[[:digit:]]+", years))
as.numeric(unlist(matches))

문자열에 여러 개의 일치 항목이있는 경우 모두 가져옵니다. 첫 번째 일치에만 관심이있는 경우 regexpr대신 사용 gregexpr하고 unlist.


1
예상하지 못했지만이 솔루션은 다른 솔루션보다 훨씬 느립니다.
Matthew Lundberg 2013 년

@MatthewLundberg the gregexpr, regexpr또는 둘 다?
sebastian-c 2013

1
gregexpr. 나는 regexpr지금까지 시도하지 않았다 . 엄청난 차이. Using regexpr은 1e6 세트에서 Andrew와 Arun의 솔루션 (두 번째로 빠른) 사이에 배치합니다. 흥미로운 점 sub은 Andrew의 솔루션을 사용해도 속도가 향상되지 않는다는 것입니다.
매튜 런드 버그

이것은 소수점을 기준으로 분할됩니다. 예를 들어 2.5는 c ( '2', '5')가됩니다
MBorg

66

업데이트 이후 extract_numeric사용되지 않습니다, 우리가 사용할 수 있습니다 parse_number에서 readr패키지로 제공된다.

library(readr)
parse_number(years)

여기에 또 다른 옵션이 있습니다. extract_numeric

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

2
이 응용 프로그램에는 좋지만 parse_number음수로 재생되지는 않습니다. 시도 parse_number("–27,633")
쐐기풀

예 @Nettle, 맞아이며, 그것은뿐만 아니라 여러 인스턴스가되지 작동하는지
akrun

3
음의 번호 구문 분석 버그가 수정되었습니다 : github.com/tidyverse/readr/issues/308 readr::parse_number("-12,345") # [1] -12345
러스 하이드

35

다음은 더 간단한 Perl과 유사한 정규식을 사용하는 Arun의 첫 번째 솔루션에 대한 대안입니다.

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

as.numeric(sub("\\D+","",years)). 또는 다음, 후 | 및 이전에 문자가 있다면gsub
Onyambu

21

또는 간단히 :

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

19

stringr파이프 라인 솔루션 :

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

Joe에게 감사하지만이 답변은 문자열의 숫자 앞의 음수 기호를 추출하지 않습니다.
Miao Cai

16

모든 문자도 제거 할 수 있습니다.

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

그러나 이것은 덜 일반화 될 수 있습니다.


3
이상하게도 Andrew의 솔루션은 내 컴퓨터에서 이보다 5 배 더 빠릅니다.
Matthew Lundberg 2013 년

5

시작 위치의 문자열에서 숫자를 추출합니다.

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

4

우리는 또한 사용할 수 있습니다 str_extract에서stringr

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"


당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.