Easily Replace Characters In A String

Bulbs

“Bulbs” by Duane Storey is licensed under CC BY-NC-ND 2.0

I just discovered a very useful function in the R base package that can be used to easily replace given characters within strings – chartr() (short for character translation)

chartr(old = "a", new = "e", x = "bad")
## [1] "bed"

We then try inserting 2 characters to replace a single character.

chartr("a", "re", "brad")
## [1] "brrd"

The replacement is carried out as usual but the additional character is ignored, with no warning.

Now let’s try exchanging the first 2 arguments. We’re trying to change bred to bad

chartr("re", "a", "bred")
## Error in chartr("re", "a", "bred"): 'old' is longer than 'new'

So in this case, it can’t be done; the old cannot be longer than the new. Before discovering this function, this is what I would have done to convert bad to bed

sub("a", "e", "bad")
## [1] "bed"

It works just the same! So, what’s the big deal with chartr(). For one, the function is particularly useful when working with file paths – you don’t need to remember (or research) those funny escape sequences for regular expressions (regex). The function sub() is part of the family of functions that are used to manipulate character vectors using regex.

# Canonical path for Windows
path <- "~\\Documents\\R\\projects"
sub("\\", "/", path)
## Error in sub("\\", "/", path): invalid regular expression '\', reason 'Trailing backslash'

To fix this, we need to apply the escape sequences. But who remembers that?

sub("\\\\", "/", path)
## [1] "~/Documents\\R\\projects"

Oops. We need to apply the change to all instances where the double backslash occurs. (Side note: The reader should note that the multiple backslashes in the function call and the output totally screwed up the syntax highlighting in the last code block)

Let’s try sub’s elder sister, gsub().

gsub("\\\\", "/", path)
## [1] "~/Documents/R/projects"

Alternatively, we could use the fixed = TRUE argument to enable character replacement instead of regex.

gsub("\\", "/", path, fixed = TRUE)
## [1] "~/Documents/R/projects"

Of course, R provides an arsenal of path-manipulating functions

path.expand(path)
## [1] "C:/Users/Admn\\Documents\\R\\projects"

Okay, that didn’t quite do the trick – tilde expansion is all we have here.

The function normalizePath() would normally be enough to change all the backslashes as well as perform tilde expansion. It is, but in this case, we have a warning.

normalizePath(path, winslash = "/")
## Warning in normalizePath(path.expand(path), winslash, mustWork): path[1]="C:/
## Users/Admn\Documents\R\projects": The system cannot find the path specified
## [1] "C:/Users/Admn/Documents/R/projects"

Well, it so happens that I am using an imaginary path for this exercise. So, if one is trying to generate a string before actually creating a file or directory path, we could use this function. However, in non-interactive R sessions, we have to go into the hocus-pocus of condition handling to get the best results.

All said and done, it’s far easier to use chartr() to carry out the task. This function is a huge time-saver!

chartr("\\", "/", path)
## [1] "~/Documents/R/projects"