Converting backslashes to forward slashes in R on Windows
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.
2 comments
Sam 15 March, 2023
very helpful, thanks!
Don 25 February, 2024
At last - extremely helpful. Thanks very much!