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"