How to extract numbers from mixed strings

Viewed 151

I have a character vector of strings, that are either integers or of the form "Pn[ab]?"

> figc
 [1] "3"   "2"   "7"   "8"   "10"  "3"   "4"   "6"   "P3a" "P3b" "5"   "P9" 
[13] "1"   "13"  "15"  "18"  "21"  "22"  "5"   "6"   "9"   "1"   "13"  "14" 
[25] "15" 

I want to convert these to numbers, where, for "P3a" the result is 3, and "P9" gives 9.

I tried:

fig <- ifelse(substr(figc, 1, 1)=="P",
              as.numeric(substr(figc, 2, 1)),
              as.numeric(figc))

giving:

> fig <- ifelse(substr(figc, 1, 1)=="P",
+               as.numeric(substr(figc, 2, 1)),
+               as.numeric(figc))
Warning message:
In ifelse(substr(figc, 1, 1) == "P", as.numeric(substr(figc, 2,  :
  NAs introduced by coercion
> 
> fig
 [1]  3  2  7  8 10  3  4  6 NA NA  5 NA  1 13 15 18 21 22  5  6  9  1 13 14 15

But I get NAs for the non-numeric ones. How to fix this? I looked at the stringr package, but couldn't see anything that would help with this simple problem

3 Answers

We can use parse_number

library(readr)
parse_number(figc)
 [1]  3  2  7  8 10  3  4  6  3  3  5  9  1 13 15 18 21 22  5  6  9  1 13 14 15

data

figc <- c("3", "2", "7", "8", "10", "3", "4", "6", "P3a", "P3b", "5", 
"P9", "1", "13", "15", "18", "21", "22", "5", "6", "9", "1", 
"13", "14", "15")

Use str extractand the character class \\d:

library(stringr)
str_extract(string, "\\d+")
[1] "3" "2" "6" "3" "3" "5" "9"

Alternatively, in base R, you can use the negative character class \\D, which matches any character that is not a digit, and remove it:

gsub("\\D", "", string)

Data:

string <- c("3","2", "6", "P3a", "P3b", "5", "P9")

We could use gsub removing all letters:

as.numeric(gsub("[[:alpha:]]", "", figc))
[1]  3  2  7  8 10  3  4  6  3  3  5  9  1 13 15 18 21 22  5  6  9  1 13 14 15
Related