Thursday, August 16, 2007

Including arguments in R CMD BATCH mode

When you have multiple computers or processors at your disposal and wish to run the same script with different arguments, use the following at the command line (here described for Linux; remove the linebreak, it is just there for display purposes):

$ R CMD BATCH --no-save --no-restore '--args a=1 b=c(2,5,6)'
test.R test.out &

Where test.R is the R script file you wish to run and test.out is a text file to include the screen output of the R terminal. A key point here is that each argument must have no spaces because --args is space delimited.

To include the variables listed in --args, adapt the following code from test.R:

##First read in the arguments listed at the command line
args=(commandArgs(TRUE))

##args is now a list of character vectors
## First check to see if arguments are passed.
## Then cycle through each element of the list and evaluate the expressions.
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)

This produces the following in test.out:

> print(a*2)
[1] 2
> print(b*3)
[1] 6 15 18

14 comments:

Kevin said...

FYI, this is the first working command line args example I've seen. The R list uniformly says "help(commandArgs), HTH." which is unhelpful. Kudos.

Keith said...

Ditto what Kevin said; the R mailing list and pretty much every other google result out of 10 or so just mentioned the commandArgs() function with little illustration. Thanks!

Alex Reynolds said...

I found that the script came up with a syntax error (running R 2.4.1). Instead of:

}else{

try:

} else {

This seemed to fix the script.

gengiskanhg.geo said...

Thank you very much. This worked very well.

gengiskanhg.geo said...

Thank you very much. This worked very well.

Matthew said...

Thanks for this solution! Taking this a little further you can define a function which fetches the command line arguments.

getArgs = function() {
args=(commandArgs(TRUE))
if(length(args) > 0) {
for (i in 1:length(args)){
eval.parent (parse(text=args[[i]]))
} # end for
} # end else
} # end getArgs

Assuming the above function is stored in a local file called 'getArgs.R' the user would include the following at the start of each batch script.

source("getArgs.R")
# Set defaults first
a=1; b= c(2,3)
# Next fetch command line arguments
getArgs()

:)

Unknown said...

Useful post!
Thank you very much! Michela

zingiber said...

Thanks for this post.

As a note, Matthew's getArgs() function is not going to work because of a scoping problem. The variables defined using eval(...) will not be see outside of the getArgs() function.

Unknown said...

Thank you very much, it's been really useful!

Tom Roche said...

One more thanks, plus note that I posted an adapted (and, I believe, improved) version to Rosetta Code.

nirmalya said...

Thank you very much for this post. It really helped to run by R script with command line parameters in batch mode. Also, this is the only illustrated example I found on the web.

Omar Al Hammal said...

This has been very useful! Thanks for giving such a clear explanation!

Omar Al Hammal said...

This has been very useful! Thanks for giving such a clear explanation!

Katya said...

Yes, thanks for an actual working example