Passing arguments to an R script from command lines
This post describes how to pass external arguments to R when calling a Rscript with a command line. The case study presented here is very simple: a Rscript is called which needs, as an input, a file name (a text file containing data which are loaded into R to be processed) and which can also accept an optional additional argument (an output file name: if this argument is not provided, the program supplies one by default).
Note: The program just loads a text file containing data, filters out non numeric variables and writes a text file with remaining numeric variables only.
R style
The most natural way to pass arguments from the command line is to use the function commandArgs
. This function scans the arguments which have been supplied when the current R session was invoked. So creating a script named sillyScript.R
which starts with
#!/usr/bin/env Rscript
args = commandArgs(trailingOnly=TRUE)
and running the following command line
Rscript --vanilla sillyScript.R iris.txt out.txt
will create a string vector args
which contains the entries iris.txt
and out.txt
. Missing and default arguments can be handled this way:
# test if there is at least one argument: if not, return an error
if (length(args)==0) {
stop("At least one argument must be supplied (input file).\n", call.=FALSE)
} else if (length(args)==1) {
# default output file
args[2] = "out.txt"
}
The simple use case described in the introduction thus gives
## program...
df = read.table(args[1], header=TRUE)
num_vars = which(sapply(df, class)=="numeric")
df_out = df[ ,num_vars]
write.table(df_out, file=args[2], row.names=FALSE)
Finally, the command lines
Rscript --vanilla sillyScript.R iris.txt out.txt
or
Rscript --vanilla sillyScript.R iris.txt
will both load the file iris.txt
, filter out the non numeric variables and write the resulting data in out.txt
. Whereas running
Rscript --vanilla sillyScript.R
Error: At least one argument must be supplied (input file). Execution halted
python style
One package allows to obtain the same result in a python-like style: the package optparse. The package can be used to perform a similar task. Basically, the package contains the functions
-
make_option
to declare options, their flags, types, default values and help messages; -
OptionParser
to read the arguments passed to the R script andparse_args
to parse them according to what has been declared thanks tomake_option
.
The functions are used as follows:
#!/usr/bin/env Rscript
library("optparse")
option_list = list(
make_option(c("-f", "--file"), type="character", default=NULL,
help="dataset file name", metavar="character"),
make_option(c("-o", "--out"), type="character", default="out.txt",
help="output file name [default= %default]", metavar="character")
);
opt_parser = OptionParser(option_list=option_list);
opt = parse_args(opt_parser);
which produces a list opt
that contains all the arguments sorted by order of appearance in option_list
and which can be called by their names as declared in this object: opt$file
and opt$out
. Then, managing null arguments is performed as follows:
if (is.null(opt$file)){
print_help(opt_parser)
stop("At least one argument must be supplied (input file).\n", call.=FALSE)
}
in which the function print_help
print the help page of the option list as declared in the object option_list
.
The remaining of the function is almost unchanged:
## program...
df = read.table(opt$file, header=TRUE)
num_vars = which(sapply(df, class)=="numeric")
df_out = df[ ,num_vars]
write.table(df_out, file=opt$out, row.names=FALSE)
If the entire script is saved in a file called yasrs.R
,
Rscript --vanilla yasrs.R
will give
Usage: testScript.R [options] Options: -f CHARACTER, --file=CHARACTER dataset file name -o CHARACTER, --out=CHARACTER output file name [default= out.txt] -h, --help Show this help message and exit Error: At least one argument must be supplied (input file). Execution halted
and
Rscript --vanilla yasrs.R --help
will print the help
Usage: testScript.R [options] Options: -f CHARACTER, --file=CHARACTER dataset file name -o CHARACTER, --out=CHARACTER output file name [default= out.txt] -h, --help Show this help message and exit
and finally
Rscript --vanilla yasrs.R -f iris.txt
or
Rscript --vanilla yasrs.R -f iris.txt -o out.txt
will both create the file out.txt
as described in the introduction of this post.
My dearest Céline, I hope that this post is explicit enough so that you can make your choice. Now you know that everything can be done with R, even this kind of map.
Additional note: in addition, a reader (thank you David) has pointed out that the script can be made executable using
chmod +x sillyScript.R
and then called with the command line:
./syllyScript.R iris.txt out.txt</p>
</p>
</div>