Print unrecognized escapes ('\*') in R - r

In R (3.2.2):
print('\*') #triggers an error
print('\\*') #prints '\\*' (two backslashes)
How do I print '\*' (1 backslash)? I've read FAQ 7.3.7 and various answers here about printing literal backslashes, but they all seem to say 'use two backslashes', which doesn't work.
In case it matters, what I really want to do is
str <- sprintf("complex string \* %s %s %s",other,complex,strings),
so I can't use
cat('\\*') which does produce '\*'

I think you are after message or cat, which prints to the screen
R> message("\\*")
\*
R> cat('\\*')
\*
The print function returns an object (note the [1])
R> print('\\*')
[1] "\\*"
which you can then pass. So
## Doesn't work
R> m1 = message("\\*")
\*
R> m1
NULL
## Good to go
R> m2 = print('\\*')
[1] "\\*"
R> m2
[1] "\\*"
Hence to use with sprintf, we have
str <- sprintf("complex string \\* %s","test")
message(str)

Related

Extract last digit [duplicate]

How can I get the last n characters from a string in R?
Is there a function like SQL's RIGHT?
I'm not aware of anything in base R, but it's straight-forward to make a function to do this using substr and nchar:
x <- "some text in a string"
substrRight <- function(x, n){
substr(x, nchar(x)-n+1, nchar(x))
}
substrRight(x, 6)
[1] "string"
substrRight(x, 8)
[1] "a string"
This is vectorised, as #mdsumner points out. Consider:
x <- c("some text in a string", "I really need to learn how to count")
substrRight(x, 6)
[1] "string" " count"
If you don't mind using the stringr package, str_sub is handy because you can use negatives to count backward:
x <- "some text in a string"
str_sub(x,-6,-1)
[1] "string"
Or, as Max points out in a comment to this answer,
str_sub(x, start= -6)
[1] "string"
Use stri_sub function from stringi package.
To get substring from the end, use negative numbers.
Look below for the examples:
stri_sub("abcde",1,3)
[1] "abc"
stri_sub("abcde",1,1)
[1] "a"
stri_sub("abcde",-3,-1)
[1] "cde"
You can install this package from github: https://github.com/Rexamine/stringi
It is available on CRAN now, simply type
install.packages("stringi")
to install this package.
str = 'This is an example'
n = 7
result = substr(str,(nchar(str)+1)-n,nchar(str))
print(result)
> [1] "example"
>
Another reasonably straightforward way is to use regular expressions and sub:
sub('.*(?=.$)', '', string, perl=T)
So, "get rid of everything followed by one character". To grab more characters off the end, add however many dots in the lookahead assertion:
sub('.*(?=.{2}$)', '', string, perl=T)
where .{2} means .., or "any two characters", so meaning "get rid of everything followed by two characters".
sub('.*(?=.{3}$)', '', string, perl=T)
for three characters, etc. You can set the number of characters to grab with a variable, but you'll have to paste the variable value into the regular expression string:
n = 3
sub(paste('.+(?=.{', n, '})', sep=''), '', string, perl=T)
UPDATE: as noted by mdsumner, the original code is already vectorised because substr is. Should have been more careful.
And if you want a vectorised version (based on Andrie's code)
substrRight <- function(x, n){
sapply(x, function(xx)
substr(xx, (nchar(xx)-n+1), nchar(xx))
)
}
> substrRight(c("12345","ABCDE"),2)
12345 ABCDE
"45" "DE"
Note that I have changed (nchar(x)-n) to (nchar(x)-n+1) to get n characters.
A simple base R solution using the substring() function (who knew this function even existed?):
RIGHT = function(x,n){
substring(x,nchar(x)-n+1)
}
This takes advantage of basically being substr() underneath but has a default end value of 1,000,000.
Examples:
> RIGHT('Hello World!',2)
[1] "d!"
> RIGHT('Hello World!',8)
[1] "o World!"
Try this:
x <- "some text in a string"
n <- 5
substr(x, nchar(x)-n, nchar(x))
It shoudl give:
[1] "string"
An alternative to substr is to split the string into a list of single characters and process that:
N <- 2
sapply(strsplit(x, ""), function(x, n) paste(tail(x, n), collapse = ""), N)
I use substr too, but in a different way. I want to extract the last 6 characters of "Give me your food." Here are the steps:
(1) Split the characters
splits <- strsplit("Give me your food.", split = "")
(2) Extract the last 6 characters
tail(splits[[1]], n=6)
Output:
[1] " " "f" "o" "o" "d" "."
Each of the character can be accessed by splits[[1]][x], where x is 1 to 6.
someone before uses a similar solution to mine, but I find it easier to think as below:
> text<-"some text in a string" # we want to have only the last word "string" with 6 letter
> n<-5 #as the last character will be counted with nchar(), here we discount 1
> substr(x=text,start=nchar(text)-n,stop=nchar(text))
This will bring the last characters as desired.
For those coming from Microsoft Excel or Google Sheets, you would have seen functions like LEFT(), RIGHT(), and MID(). I have created a package known as forstringr and its development version is currently on Github.
if(!require("devtools")){
install.packages("devtools")
}
devtools::install_github("gbganalyst/forstringr")
library(forstringr)
the str_left(): This counts from the left and then extract n characters
the str_right()- This counts from the right and then extract n characters
the str_mid()- This extract characters from the middle
Examples:
x <- "some text in a string"
str_left(x, 4)
[1] "some"
str_right(x, 6)
[1] "string"
str_mid(x, 6, 4)
[1] "text"
I used the following code to get the last character of a string.
substr(output, nchar(stringOfInterest), nchar(stringOfInterest))
You can play with the nchar(stringOfInterest) to figure out how to get last few characters.
A little modification on #Andrie solution gives also the complement:
substrR <- function(x, n) {
if(n > 0) substr(x, (nchar(x)-n+1), nchar(x)) else substr(x, 1, (nchar(x)+n))
}
x <- "moSvmC20F.5.rda"
substrR(x,-4)
[1] "moSvmC20F.5"
That was what I was looking for. And it invites to the left side:
substrL <- function(x, n){
if(n > 0) substr(x, 1, n) else substr(x, -n+1, nchar(x))
}
substrL(substrR(x,-4),-2)
[1] "SvmC20F.5"
Just in case if a range of characters need to be picked:
# For example, to get the date part from the string
substrRightRange <- function(x, m, n){substr(x, nchar(x)-m+1, nchar(x)-m+n)}
value <- "REGNDATE:20170526RN"
substrRightRange(value, 10, 8)
[1] "20170526"

using str_replace_all to replace / with \

I'm working through R for Data Science and one of the exercises asks me to replace all forward slashes with backslashes. I can't get this to work.
> x <- c("//w+", "//b[aeiou]//b")
> str_replace_all(x, "/", "\\")
[1] "w+" "b[aeiou]b"
The online solution doesn't work either, as it replaces one forward slash with two backslashes.
> x <- c("//w+", "//b[aeiou]//b")
> str_replace_all(x, "/", "\\\\")
[1] "\\\\w+" "\\\\b[aeiou]\\\\b"
Edit: I'm adding this to clarify my question. I literally want the string "//" to be "\\". I can't get that to happen. Here's an example in action showing how it's not working.
This works because I have used \ correctly in the string:
> x <- "\\w+'\\w+"
> sentence <- "Open the crate but don't break the glass."
> str_extract(sentence, x)
[1] "don't"
This doesn't work. I mistakenly used / instead of \ and try to use str_replace_all to fix this:
> y <- "//w+'//w+"
> z <- str_replace_all(y, "/", "\\\\")
> str_extract(sentence, z)
[1] NA
That's because z is not "\\w+'\\w+" like I want it to be, but rather:
> z
[1] "\\\\w+'\\\\w+"
The solution given online is actually working correctly! The extra backslashes that you're seeing are the escape characters necessary for other functions to correctly interpret the presence of \ characters.
The following commands:
x <- c("//w+", "//b[aeiou]//b")
y <- str_replace_all(x, "/", "\\\\")
Produce new vector y. When printed to the R console, you'll see this:
[1] "\\\\w+" "\\\\b[aeiou]\\\\b"
This looks wrong, but it isn't. Again, the extra backslashes are there to escape the literal backslashes. If you feed these strings to a function that interprets strings, you'll see that the string representation is actually correct, with each forward slash replaced with a backslash:
message(y)
\\w+\\b[aeiou]\\b
cat(y)
\\w+ \\b[aeiou]\\b
str_replace_all(x, "/", "\\\\")andstr_replace_all(x, "/", "\\")both are working in r for this problem

R: No quotes when passing a string as an argument

I would like to know how to make R treat an argument as a string even if it does not have quotes. Perhaps with unknown function bar:
foo <- function(x) bar(a))
foo(a abadsf 23)
[1] "a abadsf 23"
Is this doing what you want?
printname <- function(x) deparse(substitute(x))
printname(foo)
[1] "foo"
printname(bar)
[1] "bar"
edit:
This probably won't be considered acceptable, depending on where these values are coming from, but to include spaces you could try something like:
print.input = function(y=readline()) return(y)
usage in script:
print.input()
input with spaces
[1] "input with spaces"
You can use quote, but this doesn't work with spaces.
deparse(quote(abc))
## [1] "abc"
deparse(quote(abc 1))
## Error: unexpected numeric constant in "deparse(quote(abc 1"

How similar is print command in R to printf in C

How similar is print command in R to printf in C? I want to write a command printf(%s, variable) in R? Any suggestions how to do that?
My code:
v <- "abc"
print(sprintf(%s, v)
Error: unexpected input in "print(sprintf(%s, v)"
You have two errors:
R> v <- "abc"
R> print(sprintf("%s", v))
[1] "abc"
The first was to not write the format string as a string in quotes. The second was a missing closing parenthesis.
But you probably want this as an argument to cat() where you want to end a newline in one of two places:
R> cat(sprintf("%s", v), "\n")
abc
R> cat(sprintf("%s\n", v))
abc
R>

How to use R's sprintf to create fixed width strings with fill whitespace at the END?

I have vector of strings and want to create a fixed with string out of that. Shorter strings should be filled up with white spaces. E.g.:
c("fjdlksa01dada","rau","sjklf")
sprintf("%8s")
# returns
[1] "fjdlksa01dada" " rau" " sjklf"
But how can I get the additional whitespace at the END of the string?
Note that I heard of write.fwf from the gdata package which is really nice but doesn't help much in this case, because I need to write a very specific non-standard format for an outdated old program.
Add a minus in front of the 8 to get a left-aligned padded string
That is almost more of a standard "C" rather than R question as it pertains to printf format strings. You can even test this on a command-prompt:
edd#max:~$ printf "[% 8s]\n" foo
[ foo]
edd#max:~$ printf "[%-8s]\n" foo
[foo ]
edd#max:~$
and in R it works the same for padding left:
R> vec <- c("fjdlksa01dada","rau","sjklf")
R> sprintf("% 8s", vec)
[1] "fjdlksa01dada" " rau" " sjklf"
R>
and right
R> sprintf("%-8s", vec)
[1] "fjdlksa01dada" "rau " "sjklf "
R>
Edit: Updated once I understood better what #ran2 actually asked for.
The stringr package provides str_pad:
library(stringr)
x <- c("fjdlksa01dada","rau","sjklf")
str_pad(x, width=8, side="right")
which yields:
[1] "fjdlksa01dada" "rau " "sjklf "

Resources