Is there an R equivalent of other languages triple quotes? - r

I know you can escape special characters with "\"'s, but I'm interesting in creating commands that will go to the terminal that include special characters, and these cannot read the backslashes well.
As a simplified example, I'd like to have a command that looks like:
echo hello "w" or'l'd
Which could be achieved by something like
system(command="""echo hello "w" or'l'd""")
But R doesn't handle triple quotes. Is there another way? Even catching the output from cat() would be ok. e.g. newCommand = cat("echo hello \"w\" orld")
Thanks.

You can escape the " with \". I would also use shQuote if your intention is to run system commands. It takes care of the relevant escaping for you...
shQuote( "hello \"w\" orld" , type = "cmd" )
#[1] "\"hello \\\"w\\\" orld\""
You should be aware that what you see on-screen in the R interpreter is not exactly what the shell will see.. e.g.
paste0( "echo " , shQuote( "hello \"w\" orld" , type = "sh") )
#[1] "echo 'hello \"w\" orld'"
system( paste0( "echo " , shQuote( "hello \"w\" orld" , type = "sh") ) )
#hello "w" orld

You can use single quotes:
system(command='echo hello "w" orld')

Raw characters were introduced in R 4.0.0, released 2020-04-27:
There is a new syntax for specifying raw character constants similar
to the one used in C++: r"(...)" with ... any character sequence not
containing the sequence ‘⁠)"⁠’. This makes it easier to write strings
that contain backslashes or both single and double quotes. For more
details see ?Quotes.
> cat(r"(echo hello "w" or'l'd)")
echo hello "w" or'l'd

library(glue)
glue('echo hello "w" or{single_quote("l")}d')
OR
glue('echo hello "w" or{l}d', l = "'l'")

Related

Regular expression meaning in R : "( \n|\n )"

I am new to R programming and was trying out the gsub function for text replacement in pandas dataframe series(i.e new_text).
It a vast series so will not be able to print all here.
It is just a series with strings containing postal address.
I came across this gsub code : gsub(pattern = "( \n|\n )", replacement = " ", x = new_text) -> new_text
can you please let me know the meaning of this regex expression as well as the python alternative using regex expression.
Your pattern, slightly rewritten, is [ ]\n|\n[ ], which says to match:
[ ]\n a space followed by a newline
| OR
\n[ ] a newline followed by a space
Note that you might be able to use [ ]?\n[ ]? to the same effect, depending on the actual text you are using with gsub.

R: dealing with " " symbols

I am using the R programming language. I am copying text data from a website that contains many quotation marks, i.e. "" . When I try to create a data frame that contains this text, I will get an error because of conflicting "" symbols.
For example:
a <- " "blah" blah blah"
Error: unexpected symbol in "a <- " "blah"
Normally, I would have tried to use the gsub() function to remove these quotation marks from the data frame, but I can not even create the data frame to begin with. Of course, I could bring this text into a word processing software and click " ctrl + H" to replace all quotation marks ("") with an empty space (). But is there a way to do this in R itself?
Thanks
The typical way you would handle this would be to escape the literal double quotes with backslash:
a <- " \"blah\" blah blah"
[1] " \"blah\" blah blah"
You could also wrap your string literal inside single quotes and then not even have to escape the double quotes:
a <- ' \"blah\" blah blah'
[1] " \"blah\" blah blah"

Template literals in R

In JavaScript, template literals may be used to insert a dynamic value into text.
Here is an example:
const name = "John";
console.log(`Hello ${name}, how are you?`;)
This would print Hello John, how are you? to the console.
An approach to this in R would be to use paste0
name = "John"
print(paste0("Hello ", name, ", how are you?"))
This becomes quite a hassle if you are dealing with long texts that require multiple dynamic variables.
What are some alternatives to template literals in R?
You can also use str_glue from the stringr package to directly refer to an R object:
library(stringr)
name = "John"
str_glue("Hello {name}, how are you?")
# Hello John, how are you?
Take a look at the versatile sprintf()-function
name = "John"
sprintf( "Hello %s, how are you", name )
#[1] "Hello John, how are you"

combining strings to one string in r

I'm trying to combine some stings to one. In the end this string should be generated:
//*[#id="coll276"]
So my inner part of the string is an vector: tag <- 'coll276'
I already used the paste() method like this:
paste('//*[#id="',tag,'"]', sep = "")
But my result looks like following: //*[#id=\"coll276\"]
I don't why R is putting some \ into my string, but how can I fix this problem?
Thanks a lot!
tldr: Don't worry about them, they're not really there. It's just something added by print
Those \ are escape characters that tell R to ignore the special properties of the characters that follow them. Look at the output of your paste function:
paste('//*[#id="',tag,'"]', sep = "")
[1] "//*[#id=\"coll276\"]"
You'll see that the output, since it is a string, is enclosed in double quotes "". Normally, the double quotes inside your string would break the string up into two strings with bare code in the middle:
"//*[#id\" coll276 "]"
To prevent this, R "escapes" the quotes in your string so they don't do this. This is just a visual effect. If you write your string to a file, you'll see that those escaping \ aren't actually there:
write(paste('//*[#id="',tag,'"]', sep = ""), 'out.txt')
This is what is in the file:
//*[#id="coll276"]
You can use cat to print the exact value of the string to the console (Thanks #LukeC):
cat(paste('//*[#id="',tag,'"]', sep = ""))
//*[#id="coll276"]
Or use single quotes (if possible):
paste('//*[#id=\'',tag,'\']', sep = "")
[1] "//*[#id='coll276']"

sed command - branching to label

I am not able to get the same output as the example given in the SED tutorial for branching below,
http://www.grymoire.com/Unix/Sed.html#uh-59
Quoting the code here:
#!/bin/sh
sed '
:again
s/([ ^I]*)//
t again
'
The spaces are still in the brackets after this filter.
[UPDATE]
Here is my output:
$echo "( ( test ) )" | sed '
> :again
> s/([ ]*)//
> t again
> '
( ( test ) )
$
Shouldn't that be ((test))?
How do I get the script to delete the blank spaces in the nested parenthesis as demonstrated by the author?
[/UPDATE]
[UPDATE2]
$echo " ( ( ) ) " | sed '
> :again
> s/\([ ]*\)//
> t again
> '
Prompt is not back.
[/UPDATE2]
Also how do I enter the "^I" character? I think it is the horizontal tab, but I am not able to key in like other control characters via puTTY(for eg, to get "Enter", I type "Ctrl-V" followed by the "Enter" key, but this isn't working for tab). I tried with spaces only(using regex [ ]* instead of [ ^I]*), but this also failed to work.
Bully for you to work thru some tutorials.
Assuming you're using vi or vim all you need to do to include a tab char inside the [ .. ] grouping, is to type the tab key. ( I use putty all the time, and if pressing tab char doesn't "insert" a tab char into document/command-line, then you have a putty configuration problem ).
The ^I is from the vi list mode. List mode is handy to see where are line-feed chars (\n) will show as the reg-exp char $ (which in reg-ex is an "end-of-line anchor", the other being ^ char (beginning of line)).
So turning on vi list mode, with :li and you'll see all tab chars expanded as ^I and all end of lines as $
As you say
How do I get the script to delete the blank spaces in the nested parenthesis as demonstrated
That is slightly ambiguous, as newer seds use plain parens as grouping chars to create replacement group like \1 for the replacement-side of the s/pat/repl/ substitute cmd.
Given that your example has no numbered-replacement value in the replacement-side, I'll assume that the purpose is the remove a literal () pair AND that it should work as indicated. Once you :set list, add a tab-char inside the [ ... ], it should work. If not, please edit your question with any error messages that might appear.
I hope this helps.
( test ) does not match the regex ([ ]*). ([ ]*) only matches strings that contain nothing but spaces inside parens. Perhaps you are looking for ([ ]* to remove leading spaces inside and [ ]*) to remove trailing spaces.

Resources