2013-07-02

Parse arguments of an R script

R can be used also as a scripting tool. We just need to add shebang in the first line of a file (script):

#!/usr/bin/Rscript

and then the R code should follow.

Often we want to pass arguments to such a script, which can be collected in the script by the commandArgs() function. Then we need to parse the arguments and conditional on them do something. I came with a rather general way of parsing these arguments using simply these few lines:

## Collect arguments
args <- commandArgs(TRUE)
 
## Default setting when no arguments passed
if(length(args) < 1) {
  args <- c("--help")
}
 
## Help section
if("--help" %in% args) {
  cat("
      The R Script
 
      Arguments:
      --arg1=someValue   - numeric, blah blah
      --arg2=someValue   - character, blah blah
      --arg3=someValue   - logical, blah blah
      --help              - print this text
 
      Example:
      ./test.R --arg1=1 --arg2="output.txt" --arg3=TRUE \n\n")
 
  q(save="no")
}
 
## Parse arguments (we expect the form --arg=value)
parseArgs <- function(x) strsplit(sub("^--", "", x), "=")
argsDF <- as.data.frame(do.call("rbind", parseArgs(args)))
argsL <- as.list(as.character(argsDF$V2))
names(argsL) <- argsDF$V1
 
## Arg1 default
if(is.null(args$arg1)) {
  ## do something
}
 
## Arg2 default
if(is.null(args$arg2)) {
  ## do something
}
 
## Arg3 default
if(is.null(args$arg3)) {
  ## do something
}
 
## ... your code here ...
Created by Pretty R at inside-R.org

It is some work, but I find it pretty neat and use it for quite a while now. I do wonder what others have come up for this task. I hope I did not miss some very general solution.

3 comments:

nxskok said...

I use package "batch". I run R from the command line like this:

R --vanilla --args w 0.5 mg 10 < test.r

then inside test.r is

library(batch)
parseCommandArgs()

and after that, in my namespace, w is 0.5 and mg is 10.

I don't know whether that's easier or harder than your way, but it seems to work for me.

dickoa said...

Great post but you might consider also the more general optparse package

Unknown said...

argsL not args for the if statements