How can I suppress the line numbers output using R CMD BATCH? - r

If I have an R script:
print("hi")
commandArgs()
And I run it using:
r CMD BATCH --slave --no-timing test.r output.txt
The output will contain:
[1] "hi"
[1] "/Library/Frameworks/R.framework/Resources/bin/exec/x86_64/R"
[2] "-f"
[3] "test.r"
[4] "--restore"
[5] "--save"
[6] "--no-readline"
[7] "--slave"
How can i suppress the line numbers[1]..[7] in the output so only the output of the script appears?

Use cat instead of print if you want to suppress the line numbers ([1], [2], ...) in the output.
I think you are also going to want to pass command line arguments. I think the easiest way to do that is to create a file with the RScript shebang:
For example, create a file called args.r:
#!/usr/bin/env Rscript
args <- commandArgs(TRUE)
cat(args, sep = "\n")
Make it executable with chmod +x args.r and then you can run it with ./args.r ARG1 ARG2
FWIW, passing command line parameters with the R CMD BATCH ... syntax is a pain. Here is how you do it: R CMD BATCH "--args ARG1 ARG2" args.r Note the quotes. More discussion here
UPDATE: changed shebang line above from #!/usr/bin/Rscript to #!/usr/bin/env Rscript in response to #mbq's comment (thanks!)

Yes, mbq is right -- use Rscript, or, if it floats your boat, littler:
$ cat /tmp/tommy.r
#!/usr/bin/r
cat("hello world\n")
print(argv[])
$ /tmp/tommy.r a b c
hello world
[1] "a" "b" "c"
$
You probably want to look at CRAN packages getopt and optparse for argument-parsing as you'd do in other scripting languages/

Use commandArgs(TRUE) and run your script with Rscript.
EDIT: Ok, I've misread your question. David has it right.

Stop Rscript from command-numbering the output from print
By default, R makes print(...) pre-pend command numbering to stdout like this:
print("we get signal")
Produces:
[1] "we get signal"
Rscript lets the user change the definition of functions like print, so it serves our purpose by default:
print = cat
print("we get signal")
Produces:
we get signal
Notice the command numbering and double quoting is gone.
Get more control of print by using R first class functions:
my_print <- function(x, ...){
#extra shenanigans for when the wind blows from the east on tuesdays, go here.
cat(x)
}
print = my_print
print("we get signal")
Prints:
we get signal
If you're using print as a poor mans debugger... We're not laughing at you, we're laughing with you.

Related

R, STDIN to Rscript

I am trying to make a R script - test.R - that can take either a file or a text string directly from a pipe in unix as in either:
file | test.R
or:
cat Sometext | test.R
Tried to follow answers here and here but I am clearly missing something. Is it the piping above or my script below that gives me a error like:
me#lnx: cat AAAA | test.R
bash: test.R: command not found
cat: AAAA: No such file or directory
My test script:
#!/usr/bin/env Rscript
input <- file("stdin", "r")
x <- readLines(input)
write(x, "")
UPDATE.
The script:
#!/usr/bin/env Rscript
con <- file("stdin")
open(con, blocking=TRUE)
x <- readLines(con)
x <- somefunction(x) #Do something or nothing with x
write(x,"")
close(con)
Then both cat file | ./test.R and echo AAAA | ./test.R yield the expected.
I still like r over Rscript here (but then I am not unbiased in this ...)
edd#rob:~$ (echo "Hello,World";echo "Bye,Bye") | r -e 'X <- readLines(stdin());print(X)' -
Hello,World
Bye,Bye
[1] "Hello,World" "Bye,Bye"
edd#rob:~$
r can also read.csv() directly:
edd#rob:~$ (echo "X,Y"; echo "Hello,World"; echo "Bye,Bye") | r -d -e 'print(X)' -
X Y
1 Hello World
2 Bye Bye
edd#rob:~$
The -d is essentially a predefined 'read stdin into X via read.csv' which I think I borrowed as an idea from rio or another package.
Edit: Your example works with small changes:
Make it executable: chmod 0755 ex.R
Pipe output in correctly, ie use echo not cat
Use the ./ex.R notation for a file in the current dir
I changed it to use print(x)
Then:
edd#rob:~$ echo AAA | ./ex.R
[1] "AAA"
edd#rob:~$
I generally use R from a terminal application (BASH shell). I have only done a few experiments with Rscript, but including the #! line allows the script to be run in R, while permitting the use of RScript to generate an executable file. I have to use chmod to set the executable flag on my test file. Your call to write() should print the same output to the console in R or RScript, but if I want to save my output to a file I call sink("fileName") to open the connection and sink() to close it. This generally gives me control of the output and how it is rendered. If I called my script "myScript.rs" and made it executable (chmod u+x myScript.rs) I can type something like ./myScript.rs to run it and get the output on OS X or Linux. Instead of a pipe | you might try redirection > or >> to create or append.

R or bash command line length limit

I'm developing a bash program that execute a R oneliner command to convert a RMarkdown template into a HTML document.
This R oneliner command looks like:
R -e 'library(rmarkdown) ; rmarkdown::render( "template.Rmd", "html_document", output_file = "report.html", output_dir = "'${OUTDIR}'", params = list( param1 = "'${PARAM1}'", param2 = "'${PARAM2}'", ... ) )
I have a long list of parameters, let's say 10 to explain the problem, and it seems that the R or bash has a command line length limit.
When I execute the R oneliner with 10 parameters I obtain a error message like this:
WARNING: '-e library(rmarkdown)~+~;~+~rmarkdown::render(~+~"template.Rmd",~+~"html_document",~+~output_file~+~=~+~"report.html",~+~output_dir~+~=~+~"output/",~+~params~+~=~+~list(~+~param1~+~=~+~"param2", ...
Fatal error: you must specify '--save', '--no-save' or '--vanilla'
When I execute the R oneliner with 9 parameters it's ok (I tried different combinations to verify that the problem was not the last parameter).
When I execute the R oneliner with 10 parameters but with removing all spaces in it, it's ok too so I guess that R or bash use a command line length limit.
R -e 'library(rmarkdown);rmarkdown::render("template.Rmd","html_document",output_file="report.html",output_dir="'${OUTDIR}'",params=list(param1="'${PARAM1}'",param2="'${PARAM2}'",...))
Is it possible to increase this limit?
This will break a number of ways – including if your arguments have spaces or quotes in them.
Instead, try passing the values as arguments. Something like this should give you an idea how it works:
# create a script file
tee arguments.r << 'EOF'
argv <- commandArgs(trailingOnly=TRUE)
arg1 <- argv[1]
print(paste("Argument 1 was", arg1))
EOF
# set some values
param1="foo bar"
param2="baz"
# run the script with arguments
Rscript arguments.r "$param1" "$param2"
Expected output:
[1] "Argument 1 was foo bar"
Always quote your variables and always use lowercase variable names to avoid conflicts with system or application variables.

Executing R Script in Unix with parameters

In the Unix script, is there any way to run R files but with arguments in the Unix script?
I know that to run R files in that system, you will need to type "R -f "file" but what codes do you need in R so that you will need to type this instead on Unix:
"R -f "file" arg1 arg2"
Here is an example. Save this code in test.R:
#!/usr/bin/env Rscript
# make this script executable by doing 'chmod +x test.R'
help = cat(
"
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Help text here
Arguments in this order:
1) firstarg
2) secondarg
3) thirdarg
4) fourtharg
./test.R firstarg secondarg thirdarg fourtharg
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
\n\n")
# Read options from command line
args = commandArgs(trailingOnly = TRUE)
if(is.element("--help", args) | is.element("-h", args) | is.element("-help", args) | is.element("--h", args)){
cat(help,sep="\n")
stop("\nHelp requested.")
}
print(args)
Do chmod +x test.R
Then invoke it using ./test.R a b c d. It should print: [1] "a" "b" "c" "d".
You can access each of the args by doing args[1] to get to a and args[4] to get to d.
The suggestion to use Rscript does seem useful but possibly not what is being asked. One can also start R from the command line with an input file that gets sourced. The R interpreter can access the commandArgs in that mode as well. This is a minimal "ptest.R" file in my user directory that is also my default working directory:
ca <- commandArgs()
print(ca)
From a Unix command line I can do:
$ r -f ~/ptest.r --args "test of args"
And R opens, displays the usual startup messages and announces packages loaded by .Rprofile and then:
> ca <- commandArgs()
> print(ca)
[1] "/Library/Frameworks/R.framework/Resources/bin/exec/R"
[2] "-f"
[3] "/Users/davidwinsemius/ptest.r"
[4] "--args"
[5] "test of args"
>
>
And then quits.

batch mode quoted parameters parsing

I'm trying to use my R script in batch mode, but R doesn't seem able to parse quoted parameters properly:
args=(commandArgs(TRUE))
for(i in 1:length(args)){
print(paste('ARG ',i,args[[i]],sep=" "))
}
Then if a parameter with spaces and quotes is supplied, like:
R CMD BATCH "--args foo=2 bar=3 's=string with spaces'" test-parameters.R output
the output is:
[1] "ARG 1 foo=2"
[1] "ARG 2 bar=3"
[1] "ARG 3 's=string"
[1] "ARG 4 with"
[1] "ARG 5 spaces'"
of course I'd like the third parameter to be s='string with spaces': is there a way to obtain that?
Thank you!
Yeah, R CMD BATCH acts a little weird.
Try this instead:
R --slave --vanilla --file=test-parameters.R --args foo=2 bar=3 "s=string with spaces" > output
The --slave and --vanilla options might be replaced with more suitable options as needed.
To stick with R CMD BATCH, I ended passing the argument with a caret where a space is needed, and then performing a gsub("^"," ",argumentPassed,fixed=TRUE)
Batch Script
R CMD BATCH --no-restore "--args automationRDS='//networkLocation/folder/folder/my^filename^has^spaces.RDS'" "\\networkLocation\folder\folder\RScript.R"
Within R
automationRDS <- gsub("^"," ",automationRDS,fixed=TRUE)
I like the logging feature of R CMD BATCH vs Rscript

Is there a package to process command line options in R?

Is there a package to process command-line options in R?
I know commandArgs, but it's too basic. Its result is basically the equivalent to argc and argv in C, but I'd need something on top of that, just like boost::program_options in C++, or GetOptions::Long in perl.
In particular, I'd like to specify in advance what options are allowed and give an error message if the user specifies something else.
The call would be like this (with user options --width=32 --file=foo.txt):
R --vanilla --args --width=32 --file=foo.txt < myscript.R
or, if Rscript is used:
myscript.R --width=32 --file=foo.txt
(Please don't say, "why don't you write it yourself, it's not that hard". In other languages you don't have to write it yourself either. :)
getopt for R
How about commandArgs with eval for a built in solution?
test.R
## 'trailingOnly=TRUE' means only parse args after '--args'
args=(commandArgs(trailingOnly=TRUE))
## Supply default arguments
if(length(args)==0){
print("No arguments supplied.")
##supply default values
a = 1
b = c(1,1,1)
}else{
for(i in 1:length(args)){
eval(parse(text=args[[i]]))
}
}
print(a*2)
print(b*3)
and to invoke it
R CMD BATCH --no-save --no-restore '--args a=1 b=c(2,5,6)' test.R test.out
The usual caveats w.r.t using eval apply of course.
Shamelessly stolen from this blog post.

Resources