Converting backslashes to forward slashes in R on Windows

R

8 June, 2020



C:\this\is\a\typical\filepath\ that\I\find\myself\copying\ and\pasting\into\R. If you've ever done the same, you'll know how fun it is going through and substituting the backslashes for forward slashes so you can set your input or outputs correctly formatted. I've found myself doing this more and more often, so I decided to figure out a way of speeding up the process.

Why is life so hard?

I initially thought I'd write a function to do this, with a single argument taking a string and converting all the backslashes into forward slashes. Something like this:

convert_slashes <- function(string) {
    ## do the things
    return (formatted_string)
}

For example,

convert_slashes("C:\cool\path\")
[1] "C:/cool/path/"

The problem with this approach is that our Windows filepaths just have one backslash... Let's just print a string to show you what I mean:

"C:\elephant"
Error: '\e' used without hex digits in character string starting ""C:\u"

Let's find a dead end

We need a way to pretend that those backslashes aren't escape characters. One way we can do this is using the base R function, scan. This function helps us read data into a vector. The first argument that we provide, what, lets us specify that we're reading the chr data type. By not providing a file argument, we'll be prompted to pass in the character to be read on the next line. Finally, the other important parameter of note is allowEscapes, which lets us specify whether we want to process those escape characters or read them in verbatim. We leave the default setting as FALSE, since we don't want to process them.

So, we apply the scan function on our character string "C:\elephant\buffalo", then print it out:

x <- scan(what = "character")
"C:\elephant\buffalo"
print(x)
[1] "C:\\elephant\\buffalo"

Okay, this is good progress! We've escaped our escape character. Now we should be able to gsub the backslashes into forward slashes:

gsub("\\\\", "/", x)
[1] "C:/elephant/buffalo"

Note that our pattern argument in the gsub call is set to "\\\\"; we're escaping our escape characters, so this ends up looking for "\\" and replacing it with "/"!

Okay, but can we wrap this into a function? You might think about doing something like this:

convert_slashes <- function(string) {
    
    # read our string, converting single backslashes into double backslashes
    x <- scan(what = "character")
    string

    # substitute backslashes with forward slashes
    gsub("\\\\", "/", x)
}

Unfortunately, as soon as we pass in our string as an argument, it'll throw an error because it still has to read it in with the escape characters escaping nothing! In other words, we kind of need to process our string before we pass it into our function to process it... sigh.

Why is life so amazing?

And this is when I discovered the nifty little function readClipboard. This is a Windows-only function (which is sweet, because we're the only ones who'd have this issue) that simply prints out whatever is in the Windows clipboard when it's called. But the real winner? It escapes our backslashes!

Try it out for yourself by opening up File Explorer, copying the path, and calling readClipboard (with no arguments) in R. It'll turn a directory that looks like this: C:\buffalo\corgi\ into this: C:\\buffalo\\corgi\\. Perfect. Now, we can wrap that in our original gsub call, and make a new function:

convert_clip <- function() {
    gsub("\\\\", "/", readClipboard())
}

Then, you simply copy a filepath, call convert_clip(), and your nicely formatted, R-friendly filepath will be returned!

The end

My next post will be about how I've thrown my Windows PC out and replaced it with a Linux box.

Thanks to Sacha Epskamp for talking about scan in this Stack Overflow post.



0 comments

Leave a comment