nouse
nouse

Reputation: 3471

Adding leading zeros inbetween mixed strings

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

Answers (2)

G. Grothendieck
G. Grothendieck

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

Ronak Shah
Ronak Shah

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

Related Questions