I am trying to store the special escape character \ in R as part of a string.
x = "abcd\efg"
# Error: '\e' is an unrecognized escape in character string starting ""abcd\e"
x = "abcd\\efg"
# Works
The problem is that x is actually a password that I am passing as part of an API web call so I need to find a way for the string to store a literal single slash in order for this to work.
Example using the ignoring literal command:
> x = r"(abcd\efg)"
> y = "https://url?password="
> paste(x, y, sep = "")
[1] "abcd\\efg123"
> # What I need is for it to return
[1] "abcd\efg123"
> z = paste(y, x, sep = "")
> z
[1] "https://url?password=abcd\\efg"
> cat(z)
https://url?password=abcd\efg
When I pass z as part of the API command I get "bad credentials" message because it's sending \\ as part of the string. cat returns it to the console correctly, but it appears to not be sending it the same way it's printing it back.
Like everyone else in the comments said, the string appears to be handled correctly by R. I would assume it becomes a trouble somewhere else down the line. Either the API or the pass-matching software itself might be doing something with it.
As one example, the backslash will not work in most browsers if written verbatim, you would need to use %5C instead. Here is one discussion about it.
So in your case - try replacing the backslash with something else, either %5C or, as #Roland mentioned in the comments, some extra back-slash symbols, like \\\\ or \\\ or \\. And then see if any of them work.
The answers and comments contain the solution, but for completeness ill post an answer that matches my specific situation.
My package expects the user to supply a password. If there is a \ in the password the command will fail as stated above. The solution seems to be to take care of it on the input rather than trying to alter the value once the user submits the password.
library(RobinHood)
# If the true password is: abc\def
# The following inputs will all work
rh <- RobinHood("username", pwd = r"(abc\def)")
rh <- RobinHood("username", pwd = "abc\\def")
rh <- RobinHood("username", pwd = "abc%5Cdef")
Related
I want let a string like "ab'" become "ab\'"
I have tried following code
aa="ab'"
aa<-gsub("'","\\'",aa)
show ab'
aa="ab'"
aa<-gsub("'","\\\'",aa)
show ab'
aa="ab'"
aa<-gsub("'","\\\\'",aa)
show ab\\'
I don't know how to fixed it
please give me some suggest
In the case of the following code:
aa <- "ab'"
aa <- gsub("'", "\\\\'", aa)
In fact you are replacing a single quote with a single literal backslash. The output you see ab\\' I believe just shows an extra backslash to let you know that it is not an escape character.
Consider the following extension of your code:
gsub("\\\\", "A", gsub("'","\\\\'",aa))
[1] "abA'"
We can clearly see that there is only a single A in the replacement, implying that there was only a single backslash to be replaced.
Even though on the terminal, you sometimes see "\\" it is actually just "\".
Print the result using writeLines() to see the actual string:
> original_string = "ab'"
> new_string = gsub("'","\\\\",original_string)
> writeLines(new_string)
ab\
Bonus funny: https://xkcd.com/1638/
I would like to read in one character at a time and convert it to a string command to execute once a space is entered.
I tried
con <- file("stdin")
open(con, blocking=TRUE)
while(q!=" "){
#q=scan("",what="", nmax=1)
q=readChar(con,1)
cmd[i]=q;i=i+1
}
eval(cmd)
but I seem to not understand readChar() correctly.
Interesting question, but with a few flaws:
you use q, cmd and i and never assign them which leads to immediate error and program abort on undefined symbols being used in tests or assignments
you test for q at the top of your while loop but never give it a value (related to previous point)
you assign in the vector with i but never set to 1 first
you misunderstand how string concatenation works
you misunderstand how input from the console works, it is fundamentally by line and not by character so your approach has a deadly design issue (and blocking makes no difference)
you terminate the wrong way; your sentinel value of '' still gets assigned.
you open a console and never close it (though that may be ok with stdin)
you grow the result var the wrong way, but that doesn't matter here compared to all the other issues
If we repair the code a little, and use better style with whitespaces, no semicolons and an <- for assignment (all personal / common preferences) we get
con <- file("stdin")
open(con, blocking=TRUE)
cmd <- q <- ""
i <- 1
while (q != " ") {
q <- readChar(con,1)
cmd[i] <- q
i <- i+1
}
print(cmd) # for exposition only
close(con)
and note the final print rather than eval, we get this (and I typed the ls command letters followed by whitespace)
$ Rscript /tmp/marcusloecher.R
ls
[1] "l" "s" " "
$
I suggest you look into readLines() instead.
And now that I checked, I see that apparently you also never accept an answer to questions you asked. That is an ... interesting outcome for someone from our field which sometimes defines itself as being all about incentives...
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?
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.
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.
I need some help with R programming.
Basically I need to get user input from the user and use it as a variable in my R script.
When getting the user input the following checks need to be made.
to see if missing values exist:
else Prompt user to reenter
Check to see that only alpha numeric characters are entered.
else prompt user to reenter.
allow some special characters: $,#,&, etc
White space is allowed as in first name, " ", last name.
It is unclear what you are trying to do with the else if part of your code. The nature of readline() is that it will return a string of the user's input. Are there any specific characters you don't want included in the input? You could use grepl() to identify them and prevent the user from entering them as an input.
If you are trying to ensure that the user inputs something then you should use a while loop as suggested in the comments. If you are going to use your variable in R after the function runs then you need to return() the value of v1 - the user input. If you are trying to replace the space in between the first and last name with %20 then you may want to use gsub(). See the code below.
fun1 <- function(){
v1 <- c("")
v1 <- readline(prompt='Enter your First & Last Name: ')
while (v1==""){
v1 <- readline("You forgot to enter your Name. Please try again: ")
}
return(gsub(" ", "%20", v1))
}
> "David%20Smith"
I have two variables, work.dir and my.file. This means the user would like to save my.file to work.dir. User is asked to enter work.dir path and this is where it gets tricky. If user enters work.dir path
c:/temp/
and I try to paste this with a my.name, I will get
c:/temp/my.file.
But if the user enters
c:/temp
I will get
c:/tempmy.file.
So far I've been battling this with extracting various parts of the work.dir and sticking it together to achieve consistency, but I was wondering if there's another way (that would be perhaps more resilient)?
So far this has been my solution of getting a consistent directory that can be used to be pasted together with a file name.
work.dir <- "c:/temp"
work.dir <- paste(dirname(work.dir), basename(work.dir), sep = "")
James rightfully points out that in most cases the directory will be interpreted correctly. In case this doesn't satisfy you and assuming your user knows he or she shouldn't use backslashes in his directory, you can use file.path() to solve your problem, eg like this:
makepath <- function(path,file){
path <- as.list(strsplit(path,'/')[[1]])
do.call(file.path,c(path,file))
}
If your user might use Windows backslashes (and forget he has to escape them with another backslash), you can add the following controls:
makepath <- function(path,file){
if(grepl('[^[:graph:]]',path))
stop("Invalid characters. Check you didn't use a single \\")
win <- grepl('\\\\',path)
sep <- if(win) '\\\\' else '/'
path <- as.list(strsplit(path,sep)[[1]])
do.call(file.path,c(path,file))
}
This gives :
> makepath('c:\\temp','myfile')
[1] "c:/temp/myfile"
> makepath('c:\\temp\\','myfile')
[1] "c:/temp/myfile"
> makepath('c:/temp','myfile')
[1] "c:/temp/myfile"
> makepath('c:/temp/','myfile')
[1] "c:/temp/myfile"