6

I have read some questions and answers on this topic in stack overflow but still don't know how to solve this problem:

My purpose is to transform the file directory strings in windows explorer to the form which is recognizable in R, e.g. C:\Users\Public needs to be transformed to C:/Users/Public, basically the single back slash should be substituted with the forward slash. However the R couldn't store the original string "C:\Users\Public" because the \U and \P are deemed to be escape character.

dirTransformer <- function(str){
   str.trns <- gsub("\\", "/", str)
   return(str.trns)
   }

str <- "C:\Users\Public"
dirTransformer(str)

> Error: '\U' used without hex digits in character string starting ""C:\U"

What I am actually writing is a GUI, where the end effect is, the user types or pastes the directory into a entry field, pushes a button and then the program will process it automatically.

Would someone please suggest to me how to solve this problem?

Vincent
  • 87
  • 1
  • 7
  • `"C:\\Users\\Public"` - use double backslashes to denote literal backslashes. – Wiktor Stribiżew Aug 26 '16 at 10:39
  • @WiktorStribiżew Well that means I have to manually modify the directory. My purpose to develop a function which process and transform the directory automatically without manual intervention. – Vincent Aug 26 '16 at 10:50
  • You already manually typed `str <- "C:\Users\Public"` - why not do it right and type `str <- "C:\\Users\\Public"`? Also, not `gsub("\\", "/", str)`, but `gsub("\\", "/", str, fixed=TRUE)` – Wiktor Stribiżew Aug 26 '16 at 10:54
  • 1
    @WiktorStribiżew That was just an simplified example. What I am actually writing is a GUI, where the user types or pastes the directory into a entry field, pushes a button and then the program will process it. The fixed = TRUE is a correction. Thanks – Vincent Aug 26 '16 at 10:57
  • can you try `tools::normalizePath("C:\\Users\\Public","/",TRUE")` – Silence Dogood Aug 26 '16 at 11:02

2 Answers2

5

When you need to use a backslash in the string in R, you need to put double backslash. Also, when you use gsub("\\", "/", str), the first argument is parsed as a regex, and it is not valid as it only contains a single literal backslash that must escape something. In fact, you need to make gsub treat it as a plain text with fixed=TRUE.

However, you might want to use normalizePath, see this SO thread.

Community
  • 1
  • 1
Wiktor Stribiżew
  • 607,720
  • 39
  • 448
  • 563
1
dirTransformer <- function(str){
  str.trns <- gsub("\\\\", "/", str)
  return(str.trns)
}

str <- readline()
C:\Users\Public

dirTransformer(str)

I'm not sure how you intend the user to input the path into the GUI, but when using readline() and then typing C:\Users\Public unquoted, R reads that in as:

> str
[1] "C:\\Users\\Public"

We then want to replace "\\" with "/", but to escape the "\\" we need "\\\\" in the gsub.

I can't be sure how the input from the user is going to be read into R in your GUI, but R will most likely escape the \s in the string like it does when using the readline example. the string you're trying to create "C:\Users\Public" wouldn't normally happen.

Marijn Stevering
  • 1,204
  • 10
  • 24
  • Why use a regex at all with `gsub` if OP needs to replace a literal backslash? The only thing necessary to make it work with `gsub` is to disable parsing the first argument as a regular expression with `fixed=TRUE`. – Wiktor Stribiżew Aug 26 '16 at 11:55
  • I mostly wrote the answer to show that the "C:\Users\Public" string he's testing with doesn't really happen. And besides, what is the advantage of adding an extra argument over adding 2 backslashes, is it faster with `fixed = TRUE`? It's arguably a bit cleaner/clearer, but I wouldn't say that it's a very big deal. – Marijn Stevering Aug 26 '16 at 12:03
  • Using a string replacement, no regex object is created and that *is* some overhead - or at least most people consider that an overhead. Surely not a big deal (in most cases). – Wiktor Stribiżew Aug 26 '16 at 12:04
  • This approach of using readline() is also helpful! Thanks for it. I will try to integrate it into the GUI i m writing. – Vincent Aug 27 '16 at 16:48