Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Replace letters in a template string in R

Given a "template" of a UK postcode, such as "A9 9AA", where "A" is a letter placeholder, and "9" is a number placeholder, I want to generate random postcode strings like "H8 4GB". Letters can be any uppercase letter, and numbers anything from 0 to 9.

So if the template is "AA9A 9AA" then I want strings like "WC1A 9LK". I'm ignoring for now generating "real" postcodes, so I'm not bothered if "WC1A" is a valid outward code.

I've scraped around trying to get functions from the stringi package to work, but the problem seems to be that replacing or matching the "A"s in a template will only replace the first replacement, for example:

 stri_replace_all_fixed("A9 9AA",c("A","A","A"), c("X","Y","Z"), vectorize_all=FALSE)
[1] "X9 9XX"

so it doesn't replace each "A" with each element from the replacement vector (but this is by design).

Maybe there's something in stringi or base R that I've missed - I'd like to keep it in those packages so I don't bloat what I'm working on.

The brute-force method is to split the template, do replacements, paste the result back together but I'd like to see if there's a quicker, naturally vectorised solution.

So to summarise:

foo("A9 9AA") # return like "B6 5DE"
foo(c("A9 9AA","A9 9AA","A9A 9AA")) # returns c("Y6 5TH","D4 8JH","W0Z 3KQ")

Here's a non-vectorised version which relies on constructing an expression and evaluating it...

random_pc <- function(fmt){
    cc = gsub(" ",'c(" ")',gsub("9","sample(0:9,1)",gsub("A","sample(LETTERS,1)",strsplit(fmt,"")[[1]])))
    paste(eval(parse(text=paste0("c(",paste(cc,collapse=","),")"))),collapse="")    
}

> random_pc("AA9 9AA")
[1] "KO6 1AY"
like image 566
Spacedman Avatar asked Apr 06 '18 17:04

Spacedman


People also ask

How do you replace a character in a string with another character in R?

Use str_replace() method from stringr package to replace part of a column string with another string in R DataFrame.

How do I replace a string in a value in R?

The gsub() function in R is used to replace the strings with input strings or values. Note that, you can also use the regular expression with gsub() function to deal with numbers.


1 Answers

As I understand, OP wants to randomly create UK POST CODE in specified format. I think sprintf can help like:

sprintf("%s%s %d%d%s", sample(LETTERS,1),sample(LETTERS,1), sample(0:9,1),
                sample(0:9,1), sample(LETTERS,1) )
#1] "BC 59D"

Now, if purpose is to provide the format using 9 and A then step will be to first replace 9 with %d and A with %s.

OPTION#2

Another option can be achieved using paste0 and sapply using a custom function as:

fmt <- "AA 9AA A"
paste0(sapply(strsplit(fmt,""), getCodeText), collapse = "")
#"YF 7OP Z"


#custom function to generate random characters
getCodeText <- function(x){
  retVal = x
  for(i in seq_along(x)){
    if(x[i] == "A"){
      retVal[i] = sample(LETTERS,1)
    }else if(x[i] == "9"){
      retVal[i] = as.character(sample(0:9,1))
    }
  }
  retVal
}
like image 71
MKR Avatar answered Oct 27 '22 23:10

MKR