Allow named arguments in R’s CLI
When run on the command line, a R script can be set to accept arguments by adding to the script
= commandArgs(trailingOnly=TRUE) args
If we call $ Rscript demo.R a b c
this line will create a text vector of all the arguments following script (c('a', 'b', 'c')
).
Unlike long options in Linux tools these are unnamed and must be in a fixed order. That’s suboptimal for projects using a mix of tools that do expect named arguments (Some linux and python (argparse
)) instead of purely by order. Happily, adding this functionality is simple and requires no libraries.
We’ll start by assuming that only named arguments will be passed and that all key/value pairs will be passed together1.
We’ll quickly confirm that there are an even number of arguments and then can separate the odd entries into the names (e.g. --inp_file
) and the evens into the values (e.g. ./input.txt
). The former are set as names for the latter so we now can refer to argments by name rather than index.
= commandArgs(trailingOnly=TRUE)
args
# confirm we have even arguments
stopifnot((length(args) %% 2) == 0)
<- args[seq(1, length(args), 2)]
args_names <- args[seq(2, length(args), 2)]
args_values names(args_values) <- args_names
<- args_values args
If we want to get even fancier, we can write a quick function to allow for default values. Since the arguments are named we’ll pass them through as.character()
to match the default values (alternately we could name the defaults). All arguments are provided as strings so we can coerce them to the desired data type where needed.
# apply defaults if applicable
<- function(args, key, default){
get_arg if(key %in% names(args)){
# return value without name
<- as.character(args[key])
out else {
} <- default
out
}return(out)
}
<- get_arg(args, key='--inp_file', './input.txt')
inp_file
<- get_arg(args, key='--max_iter', '10') |> as.integer() max_iter
Footnotes
Note that the following could be extended to apply only to long options so that an odd number of long and short options would not be an issue.↩︎