Reputation: 3471
I have a vector
x <- c("MB1", "MB11" ,"MB12" ,"MB13", "B1", "B11", "B12", "B13", "B2")
and would like it to convert to
x
[1]"MB01" "MB11" "MB12" "MB13" "B01" "B11" "B12" "B13" "B02"
x only contains either "MB" or "B" as leading string, followed by maximum two digits.
i know how to str_pad, so i would like to perform something like
new.vector < paste0("Any Letter you find in each element of x", str_pad("numerical elements of x", 2, pad="0"))
or any other way, which can achieve this.
Thanks!
Upvotes: 1
Views: 78
Reputation: 270075
1) gsub Remove the digits and non-digits respectively and combine back using sprintf. No packages are used.
sprintf("%s%02d", gsub("\\d", "", x), as.numeric(gsub("\\D", "", x)))
## [1] "MB01" "MB11" "MB12" "MB13" "B01" "B11" "B12" "B13" "B02"
2) trimws This variation using trimws also uses only base R.
sprintf("%s%02d", trimws(x,, "\\d"), as.numeric(trimws(x,, "\\D")))
## [1] "MB01" "MB11" "MB12" "MB13" "B01" "B11" "B12" "B13" "B02"
3) gsubfn An ever shorter solution involves extracting the digits, converting to numeric, padding and then inserting back in using gsubfn.
library(gsubfn)
gsubfn("\\d+", ~ sprintf("%02d", as.numeric(digits)), x)
## [1] "MB01" "MB11" "MB12" "MB13" "B01" "B11" "B12" "B13" "B02"
4) sub Shorter yet we can use only sub by looking for one digit suffixes and inserting a zero. No packages are used.
sub("(\\D)(\\d)$", "\\10\\2", x)
## [1] "MB01" "MB11" "MB12" "MB13" "B01" "B11" "B12" "B13" "B02"
5) Generalization If we don't know how many digits are involved and we want to use sufficient 0 padding to right justify them all then we can use * format in sprintf in this variation of (1). The same approach could be used with the others. No packages are used.
digits <- gsub("\\D", "", x)
nondigits <- gsub("\\d", "", x)
sprintf("%s%0*d", nondigits, max(nchar(digits)), as.numeric(digits))
## [1] "MB01" "MB11" "MB12" "MB13" "B01" "B11" "B12" "B13" "B02"
Upvotes: 2
Reputation: 389225
library(tidyverse)
strcapture('([A-Z]+)([0-9]+)', x,
proto = list(char = character(), num = numeric())) %>%
mutate(num = str_pad(num, 2, pad = '0')) %>%
unite(value, char, num, sep = '') %>%
pull(value)
#[1] "MB01" "MB11" "MB12" "MB13" "B01" "B11" "B12" "B13" "B02"
Upvotes: 2