Learn R Programming

getopt (version 1.17)

getopt.package: C-like getopt behavior

Description

getopt is primarily intended to be used with ``Rscript''. It facilitates writing ``#!'' shebang scripts that accept short and long flags/options. It can also be used from ``R'' directly, but is probably less useful in this context.

getopt() returns a list data structure containing names of the flags that were present in the character vector passed in under the opt argument. Each value of the list is coerced to the data type specified according to the value of the spec argument. See below for details.

Notes on naming convention:

1. An option is one of the shell-split input strings.

2. A flag is a type of option. a flag can be defined as having no argument (defined below), a required argument, or an optional argument.

3. An argument is a type of option, and is the value associated with a flag.

4. A long flag is a type of flag, and begins with the string ``--''. If the long flag has an associated argument, it may be delimited from the long flag by either a trailing =, or may be the subsequent option.

5. A short flag is a type of flag, and begins with the string ``-''. If a short flag has an associated argument, it is the subsequent option. short flags may be bundled together, sharing a single leading ``-'', but only the final short flag is able to have a corresponding argument.

Usage

getopt( spec=NULL, opt=commandArgs(TRUE), command=strsplit(commandArgs(FALSE)[4],"=")[[1]][2], usage=FALSE, debug=FALSE )

Arguments

spec
The getopt specification, or spec of what options are considered valid. The specification must be either a 4-5 column matrix, or a character vecto
opt
This defaults to the return value of commandArgs(TRUE). If R was invoked directly via the ``R'' command, this corresponds to all arguments passed to R after the ``--args'' flag.

If R was invoked via the ``

command
The string to use in the usage message as the name of the script. See argument usage.
usage
If TRUE, argument opt will be ignored and a usage statement (character string) will be generated and returned from spec.
debug
This is used internally to debug the getopt() function itself.

Details

Current issues:

1. No support for multiple, identical flags, e.g. for "-m 3 -v 5 -v", the trailing "-v" overrides the preceding "-v 5", result is v=TRUE (or equivalent typecast).

2. No support for multi-valued flags, e.g. "--libpath=/usr/local/lib --libpath=/tmp/foo".

3. No support for lists, e.g. "--define os=linux --define os=redhat" would set result$os$linux=TRUE and result$os$redhat=TRUE.

4. No support for incremental, argument-less flags, e.g. "/path/to/script -vvv" should set v=3.

5. Need more unit tests (see end of examples section).

6. Support partial-but-unique string match on options, e.g. "--verb" and "--verbose" both match long flag "--verbose".

7. No support for mixing in positional arguments or extra arguments that don't match any options. For example, you can't do "my.R --arg1 1 foo bar baz" and recover "foo", "bar", "baz" as a list. Likewise for "my.R foo --arg1 1 bar baz".

See Also

getopt

Examples

Run this code
#!/path/to/Rscript
library('getopt');
#get options, using the spec as defined by the enclosed list.
#we read the options from the default: commandArgs(TRUE).
opt = getopt(c(
  'verbose', 'v', 2, "integer",
  'help'   , 'h', 0, "logical",
  'count'  , 'c', 1, "integer",
  'mean'   , 'm', 1, "double",
  'sd'     , 's', 1, "double"
));

#help was asked for.
if ( !is.null(opt$help) ) {
  #get the script name (only works when invoked with Rscript).
  self = commandArgs()[1];
  #print a friendly message and exit with a non-zero error code
  cat(paste("Usage: ",self,"[-[vh]] [-[-mean|m] <mean>] [-[-sd|s] <sd>] [-[-count|c] <count>]
",sep=""));
  q(status=1);
}

#set some reasonable defaults for the options that are needed,
#but were not specified.
if ( is.null(opt$mean    ) ) { opt$mean    = 0     }
if ( is.null(opt$sd      ) ) { opt$sd      = 1     }
if ( is.null(opt$count   ) ) { opt$count   = 10    }
if ( is.null(opt$verbose ) ) { opt$verbose = FALSE }

#print some progress messages to stderr, if requested.
if ( opt$verbose ) { write("writing...",stderr()); }

#do some operation based on user input.
cat(paste(rnorm(opt$count,mean=opt$mean,sd=opt$sd),collapse=""));
cat("");

#signal success and exit.
#q(status=0);

### END ###
#regression tests follow.  not part of the example.
spec = c(
  'verbose', 'v', 2, "integer",
  'help'   , 'h', 0, "logical",
  'dummy1' , 'd', 0, "logical",
  'dummy2' , 'e', 2, "logical",
  'count'  , 'c', 1, "integer",
  'mean'   , 'm', 1, "double",
  'sd'     , 's', 1, "double",
  'output' , 'O', 1, "character"
);
opt = getopt(spec, c('-c', '-1', '-m', '-1.2'));
opt = getopt(spec, c('-v', '-m', '3'));
opt = getopt(spec, c('-m', '3', '-v'));
opt = getopt(spec, c('-m', '3', '-v', '2', '-v'));
opt = getopt(spec, c('-O', '-', '-m', '3'));
opt = getopt(spec, c('-m', '3', '-O', '-'));
opt = getopt(spec, c('-de'));
opt = getopt(spec, c('-ed'));
opt = getopt(spec, c('-d'));
opt = getopt(spec, c('-e', '1'));
opt = getopt(spec, c('-de', '1'));
opt = getopt(spec, c('--verbose'));
opt = getopt(spec, c('--help'));
opt = getopt(spec, c('--verbose', '--help'));
opt = getopt(spec, c('--verbose', '--mean', '5'));
opt = getopt(spec, c('--mean=5'));
opt = getopt(spec, c('--verbose', '--mean=5'));
opt = getopt(spec, c('--verbose', '--mean=5', '--sd', '5'));
opt = getopt(spec, c('--mean=5', '--sd', '5', '--verbose'));
opt = getopt(spec, c('--mean=5', '--verbose', '--sd', '5'));

spec = c(
  'date'     , 'd', 1, "character",
  'help'     , 'h', 0, "logical",
  'getdata'  , 'g', 0, "logical",
  'market'   , 'm', 1, "character",
  'threshold', 't', 1, "double"
);
opt = getopt(spec, c('--date','20080421','--market','YM','--getdata'));
opt = getopt(spec, c('--date','20080421','--getdata','--market','YM'));
opt = getopt(spec, c('--date','20080421','--getdata','--market','YM'),debug=TRUE);
print(getopt(spec, c('--date','20080421','--getdata','--market','YM'),usage=TRUE));

Run the code above in your browser using DataLab