trevorld / r-optparse Goto Github PK
View Code? Open in Web Editor NEWcommand-line optional argument parser
Home Page: http://trevorldavis.com/R/optparse/dev/
License: GNU General Public License v2.0
command-line optional argument parser
Home Page: http://trevorldavis.com/R/optparse/dev/
License: GNU General Public License v2.0
many Unix commands allow the same option to be repeated on the command line. for example, the more instances of the debug flag -d
, the more verbose the debugging output. or, for the C compiler, each instance of -I
specifies a different directory in which to look for #include
files.
also, for some applications, it's important that the options be "presented" to the program in the same order in which they appear on the command line.
it would be nice if optparse
supported this style. here's an example, using callback:
require(optparse)
cb <- function(s4, lflag, val, ps4) { cat(sprintf("cb: %s %s\n", lflag, val)) }
options <- list(
make_option(c("-i", "--include"), action="callback", type="character",
callback=cb, help="add an include directory (tree)")
)
p <- OptionParser(option_list=options)
## i should see two messages (invocations of cb()), but i only see one
args <- parse_args2(p, args=c("-i", "/usr/include", "-i", "/usr/X11/include"))
bonus points for extending the action
parameter with "append"
and "count"
actions so one doesn't always need to use callback
. (though the github's helpful "Similar issues" bit shows me #22 already asked for these.)
In version 1.0.2, option defaults were allowed to have length zero. But it seems in the latest version, this is not allowed, failing with:
Error in if (is.na(default)) { : argument is of length zero
Calls: parse_args -> print_help -> cat -> sub -> .as_string
5: parse_args(opt.parser, positional_arguments = TRUE)
4: print_help(object)
3: cat(sub("%default", .as_string(option@default), option@help))
2: sub("%default", .as_string(option@default), option@help)
1: .as_string(option@default)
any thoughts on whether support for option defaults having length zero could/should be restored?
Thanks
Ben
Mentioned here trevorld/r-getopt#9
Code like this should work:
option_list_neg <- list( make_option(c("-h", "--mean"), default=0.0) )
parser <- OptionParser(usage = "\\%prog [options] file", option_list=option_list_neg, add_help_option=FALSE)
args <- parse_args(parser, args = c("-h", "-5.0"))
expect_equal(args, list(mean = -5.0))
When using -g
as argument and calling the script on the command-line, the value of -g
is used both to set the GUI and later inside the script. A small example:
#!/usr/bin/env Rscript
suppressPackageStartupMessages( library(optparse) )
option_list = list(
make_option( c("-t", "--trait"), type="double", default=0.99,
help="trait frequency" ),
make_option( c("-g", "--generations"), type="integer", default=1000,
help="number of generations to run" ) );
opt_parser = OptionParser(option_list=option_list);
opt = parse_args(opt_parser);
write( opt$trait, stdout( ) )
write( opt$generations, stdout( ) )
Save as "script.R" and run:
./script.R -t 0.4 -g 5
WARNING: unknown gui '5', using X11
0.4
5
But:
./script -t 0.4 -g X11
Warning message:
In storage.mode(peek.optstring) = spec[current.flag, col.mode] :
NAs introduced by coercion
0.4
NA
-g
is used first to set the GUI, then to set opt$generations. If using --generations
, no warnings occur.
This SO answer claims that this is not possible: http://stackoverflow.com/a/13811415/992687 , but the answer is old.
suppressPackageStartupMessages(library("optparse"))
option_list <- list(
make_option(c("-v", "--verbose"), action="store_true", default=TRUE,
help="Print extra output [default]"),
make_option(c("-q", "--quietly"), action="store_false",
dest="verbose", help="Print little output"),
make_option(c("-c", "--count"), type="integer", default=5,
help="Number of random normals to generate [default %default]",
metavar="number")
)
parser <- OptionParser(option_list=option_list)
parse_args(
parser,
args = c("--verbose", "--count=11"))
parse_args(parser, args = c("--help"))
> sessionInfo()
R version 3.5.0 (2018-04-23)
Platform: x86_64-pc-linux-gnu (64-bit)
Running under: CentOS release 6.9 (Final)
Matrix products: default
BLAS: /opt/common/CentOS_6-dev/R/R-3.5.0/lib64/R/lib/libRblas.so
LAPACK: /opt/common/CentOS_6-dev/R/R-3.5.0/lib64/R/lib/libRlapack.so
locale:
[1] LC_CTYPE=en_US.UTF-8 LC_NUMERIC=C
[3] LC_TIME=en_US.UTF-8 LC_COLLATE=en_US.UTF-8
[5] LC_MONETARY=en_US.UTF-8 LC_MESSAGES=en_US.UTF-8
[7] LC_PAPER=en_US.UTF-8 LC_NAME=C
[9] LC_ADDRESS=C LC_TELEPHONE=C
[11] LC_MEASUREMENT=en_US.UTF-8 LC_IDENTIFICATION=C
attached base packages:
[1] stats graphics grDevices utils datasets methods base
other attached packages:
[1] optparse_1.6.0
loaded via a namespace (and not attached):
[1] compiler_3.5.0 getopt_1.20.2
library("optparse")
str2bool <- function(option, flag, option_value, parser) {
print(option_value)
s <- tolower(as.character(option_value))
if (s %in% c("0", "false", "f", "no", "n")) {
FALSE
} else {
TRUE
}
}
parser <- OptionParser()
parser <- add_option(parser, "--test", type = "character", default = FALSE, callback = str2bool)
parse_args(parser) |> print()
$help
[1] FALSE
$test
[1] "FALSE"
parse_args(parser, "--test=f") |> print()
$help
[1] FALSE
$test
[1] FALSE
This isn't something that the inspiration python module ever did:
import optparse
def str2bool(option, opt, value, parser):
setattr(parser.values, option.dest, bool(value))
parser = optparse.OptionParser()
parser.add_option("--test", action="callback", type="string",
default=False, callback=str2bool)
opts, args = parser.parse_args()
print(opts)
~/tmp$ python3 optparse_bug2.py
{'test': False}
~/tmp$ python3 optparse_bug2.py --test=True
{'test': True}
Hi,
First, I successfully set up optparse in R in Linux system. When I employ this package, it said:
Error in make_option(c("-co", "--corin"), type = "character", default = "corin.txt", :
Short flag -co must only be a '-' and a single letter
Do you have any suggestions? Thanks.
hi. thanks for doing these. (as my sister says, "no good deed goes unpunished".)
i may be missing something that's obvious, but in my simple attempt, i don't see optparse complaining about invalid options. i.e., i would think the following would give an error:
require(optparse)
options <- list(
make_option(c("-v", "--verbose"), action="store_true", default=TRUE,
help="Print extra output [default]")
)
p <- OptionParser(option_list=options)
## i would think this would fail with s.th. like "unrecognized option"
args <- parse_args2(p, args=c("-v", "-x", "--foo", "this", "that", "the other"))
the unix shell command, and, lazy that i am to check, i think getopt(3), etc., do:
{1001} getopt abc -x
getopt: invalid option -- 'x'
--
again, thanks, and sorry if i'm missing the blindingly obvious.
I'm currently working on an R package that would benefit from extending the OptionParserOption class. Would you be amenable to exporting this class so that it can be extended? I'd be happy to create a pull request with relevant changes to the roxygen comments but wanted to check with you before doing the work.
Do it when next CRAN updload
Hi I am testing a tool released in 2018. part of the script in the tools is:
''''
library(optparse)
option_list = list(
make_option(c("-id", "--patientId"), type="character", default=NULL,
help="patient ID", metavar="character"),
''''
When I ran the script, the error is "Short flag -id must only be a '-' and a single letter". So I wonder if previous version of optparse support multiple letters for short flag? Thanks!
I think this information really belongs there, and not in parse_args
. This would also provide an easy way to deprecate passing FALSE
to positional_arguments
.
Would it be possible to make the following changes to wrap long help text?
Lines 338 to 339 in 26b6627
cat('\n')
cat(paste(strwrap(sub("%default", .as_string(option@default), option@help), prefix='\t\t'), collapse='\n'))
Of course, one can supply pre-formatted text to help, but it seems laborious to call a formatter for every option compared with this change of two lines of code here?
If my understanding is correct there is no way to indicate that an argument is required and not specify a default value.
I raised the question : http://stackoverflow.com/questions/35252547/can-i-specify-mandatory-arguments-with-optparse
Am I wrong ?
getopt
ver 1.19
is 1.19.0
(not 1.19
)
Hello, I was trying to make sure the usage of a Rscript is displayed when no argument is passed the the script, similarily to when -h or --help is passed.
I did not find anything, is it possible ?
I understand it might not be doable because there are legitimate cases where no argument is expected behavior
Just a suggestion.
Python's argparse
automatically converts hyphens to underscores.
I think this behavior would suit optparse because column names containing hyphens can't be subsetted the same way as underscores:
library(optparse)
option_list <- c(make_option('--some-option'))
parser <- OptionParser(option_list = option_list)
options <- parse_args(parser)
print(options$some-option) # crashes
print(options$[,'some-option']) # ugly
print(options$some_option) # nice
What do you think? I could write the code and send you a PR if you agree.
CRAN check NOTE recently started showing up in R-devel:
Version: 1.7.3
Check: package vignettes
Result: NOTE
Package vignette with \VignetteEngine{} not specifying an engine package:
‘optparse.Rrst’
Engines should be specified as \VignetteEngine{PKG::ENG}.
No e-mail from CRAN saying it needs to be fixed in a certain time frame
if you provide a callback function, but don't specify action="callback"
, you get a warning.
and, the man page ?make_option (or ?add_option) doesn't mention "callback"
as a possible value for the action
parameter.
--no-vignettes
(no response) for the relevant machinesVersion: 1.7.4
Check: re-building of vignette outputs
Result: ERROR
Error(s) in re-building vignettes:
...
--- re-building ‘optparse.Rrst’ using knitr
sh: +RTS: command not found
Warning in system(command) : error in running command
Error: processing vignette 'optparse.Rrst' failed with diagnostics:
pandoc document conversion failed with error 127
--- failed re-building ‘optparse.Rrst’
SUMMARY: processing the following file failed:
‘optparse.Rrst’
Error: Vignette re-building failed.
Execution halted
Flavor: r-release-macos-x86_64
Hi, is there any way to pass arguments with spaces?
I currently need to pass a filename and it keeps splitting it into separate arguments, which messes up parse_args().
If not, are there any plans to?
Thanks.
hi, thanks for making such a powerful package. I met an error like this, I noticed that there is one issue about this #33
there is software called lohhla, it used all the vars like this, link is here https://github.com/mskcc/lohhla/blob/master/LOHHLAscript.R#L580-L583
it published in cell(Allele-Specific HLA Loss and Immune Escape in Lung
Cancer Evolution), so does it mean it is totally wrong?
hi. this seems a bug.
require(optparse)
p <- OptionParser()
## note lack of two dashes, i guess
parsed_args <- parse_args2(p, c("-option", "arg"))
which gives this run time error
Error in if (.requires_argument(argument, object)) is_taken <- TRUE :
argument is of length zero
cheers.
Dear Trevor,
I think that there is one more thing in the optparse package that can be improved. This is related to the negative numbers as optional arguments after short flags. Such arguments seem not to be allowed in Optparse 1.0.2 (see the code below). However, as the flags always start with a letter character (not a digit according to the manual, Feb 25, 2013), the negative numbers can always be distinguished from flags and therefore they should be parsed as numbers.
library(optparse)
optlist = list(
make_option(c("-t", "--tmin"), type="numeric",
help="Startup time [sec]. ")
)
parser = OptionParser(option_list=optlist, usage="", epilogue="")
parse_args(args=c("--tmin=-11.2"), parser) #this works
parse_args(args=c("-t", "-11.2"), parser) #error message (but I think that this should work)
Final note.
The original Python Optparse (accordingly to the POSIX specification ?) also behaves somewhat differently in what regards the negative numbers as positional arguments. It requires "-- " before entering negative numbers as positional arguments. But I think that the implementation in R is more intuitive in this case.
http://objectmix.com/python/211112-getopt-negative-numbers.html
parse_args(args=c("--tmin=5.5", "-12"), parser, positional_arguments=TRUE) #this works
parse_args(args=c("-t", "0", "-12"), parser, positional_arguments=TRUE) #this works
import optparse
parser = optparse.OptionParser()
parser.add_option("-a", type="int")
options, args = parser.parse_args(["-a", "-42", "--", "-123"]) #works
options.a
args
options, args = parser.parse_args(["-a", "-42", "-123"]) #error
I hope that this message can help to improve the Optparse package a little.
Best regards,
Miroslav Posta
checking DESCRIPTION meta-information ... NOTE
Malformed Title field: should not end in a period.
checking re-building of vignette outputs ... NOTE
Error in re-building vignettes:
...
sh: rst2pdf: command not found
Error: processing vignette 'optparse.Rrst' failed with diagnostics:
conversion by rst2pdf failed!
Execution halted
Hi,
I'm running into an error when my argument has a leading hyphen.
Code:
library(optparse)
option_list <- list(
make_option("--range", type="character", help="", dest="range")
)
optparser <- OptionParser(option_list = option_list, usage="")
opt <- parse_args(optparser)
print(opt$range)
This doesn't seem to be a problem when type is "numeric" and if I only had a single number - but I wanted an input that takes in a list of numbers, including negative numbers, so I used character instead. Any other suggestions welcomed!
Output when argument doesn't have a hyphen:
Rscript optparse_hyphen.R --range 0.1,1
[1] "0.1,1"
Output for argument with a leading hyphen:
Rscript optparse_hyphen.R --range -0.1,1
Error in getopt(spec = spec, opt = args) :
flag "range" requires an argument
Calls: parse_args -> getopt
Execution halted
Tried putting quotes around the argument but that doesn't seem to work either:
Rscript optparse_hyphen.R --range "-test"
Error in getopt(spec = spec, opt = args) :
flag "range" requires an argument
Calls: parse_args -> getopt
Execution halted
Thanks for looking into this!
Carolyn
Lines 630 to 639 in 6f4d9c0
In the above code, line 634 should be
if (!option@action %in% c("store_true", "store_false")) {
For example, I have a Rscript that could be executed through Rscript like this:
Rscript4.0.3 /home/yihsiao/PANOPLY/src/panoply_mo_nmf/mo-nmf.r -y panoply_rare_rcc_parameters_quick.yml -n 50 -z /home/yihsiao/PANOPLY/src/panoply_mo_nmf/ -t /home/yihsiao/ccRCC-nCCRCC/rare_rcc_rna_prot_phospho.tar
However, to actually debug this script, I need to get the objects, variables used in the script.
I have tried something like this, but seems not work:
commandArgs <- function(...) c("-y", "panoply_rare_rcc_parameters_quick.yml", "-n", "50", "-z", "/home/yihsiao/PANOPLY/src/panoply_mo_nmf/", "-t", "/home/yihsiao/ccRCC-nCCRCC/rare_rcc_rna_prot_phospho.tar")
source("/home/yihsiao/PANOPLY/src/panoply_mo_nmf/mo-nmf.r")
In the python version some other actions are supported for options. https://docs.python.org/3/library/optparse.html#defining-options
I'm thinking of the "append" and "count" options that are missing in this library but are often used in opt args parsing.
Is it possible to add support for these ?
The documentation for the "default" argument of "make_option" reads "The default value optparse should use if it does not find the option on the command line. Default is derived from the long flag in opt_str." [emphasis added]. This doesn't seem to make much sense, since there doesn't appear to be any documentation on how to derive the default from the long flag. Rather, the emphasized part looks like a cut-and-paste from the documention of the "dest" argument, which reads "A character string that specifies what field in the list returned by parse_args should optparse store option values. Default is derived from the long flag in opt_str."
Is there a way to specify required arguments and have parse_args
exit with an error and a help message if these args are missing?
Is it correct that you can't pass in a zero length strings as an argument? For example
Rscript sample.R --test=""
where sample.R contains
require(optparse)
get_options <- function() {
option_list <- list(
make_option("--test", type="character", default="apple")
)
parser <- OptionParser(usage="%prog [options]", option_list=option_list)
args <- parse_args(parser, positional_arguments = 0)
opt <- args$options
opt
}
print(commandArgs())
get_options()
I get the response
Loading required package: optparse
[1] "/usr/lib/R/bin/exec/R" "--slave" "--no-restore"
[4] "--file=sample.R" "--args" "--test="
Error in getopt(spec = spec, opt = args) : long flag "test=" is invalid
Calls: get_options -> parse_args -> getopt
Execution halted
So the empty quotes seem to basically disappear when R parses the arguments first.
I wasn't sure if this was the desired behavior.
Tested with R version 3.4.3 (2017-11-30); Platform: x86_64-pc-linux-gnu (64-bit)
Hello,
The opt list contains different values while executing a script by command-line (Rscript) versus RStudio. Here's the code:
#!/usr/bin/env Rscript
suppressMessages(library('optparse'))
options(show.error.locations = TRUE)
#### ARGUMENTS ####
option_list = list(
make_option(c("-i","--input"), type="character", default=NULL,
help="", metavar="character"),
make_option(c("--output", "-o"), type="character", default=NULL,
help="", metavar="character"),
make_option(c("--bootstraps", "-b"), type="integer", default=1000,
help="", metavar="integer"),
make_option(c("--predictionsNumber", "-m"), type="integer", default=NULL,
help="", metavar="integer"),
make_option(c("--bootstrapsCI", "-c"), type="numeric", default=0.95,
help="", metavar="numeric"),
make_option(c("--CPU", "-p"), type="integer", default=4,
help="", metavar="integer"),
make_option(c("--wilcoxStartBin", "-wilcoxStart"), type="numeric", default=NULL,
help="", metavar="numeric"),
make_option(c("--wilcoxEndBin", "-wilcoxEnd"), type="numeric", default=NULL,
help="", metavar="numeric"),
make_option(c("--wilcoxThreshold", "-wilcoxT"), type="numeric", default=0.05,
help="", metavar="numeric"),
make_option(c("--firstRegionName", "-name1"), type="character", default="Region1",
help="", metavar="character"),
make_option(c("--secondRegionName", "-name2"), type="character", default="Region2",
help="", metavar="character"),
make_option(c("--bootPlotWidth", "-bootW"), type="numeric", default=6,
help="", metavar="numeric"),
make_option(c("--bootPlotHeight", "-bootH"), type="numeric", default=3.7,
help="", metavar="numeric"),
make_option(c("--bootPlotColors", "-bootC"), type="character", default=NULL,
help="", metavar="character"),
make_option(c("--wilcoxPlotWidth", "-wilcoxW"), type="numeric", default=4.6,
help="", metavar="numeric"),
make_option(c("--wilcoxPlotHeight", "-wilcoxH"), type="numeric", default=3.7,
help="", metavar="numeric"),
make_option(c("--signalName", "-signal"), type="character", default="Genomic signal",
help="", metavar="character"),
make_option(c("--font", "-f"), type="character", default=NULL,
help=".", metavar="character")
);
opt_parser = OptionParser(description= "", usage = "", option_list=option_list);
opt = parse_args(opt_parser);
opt
Under RStudio, the none given arguments are NULL in the opt
list (they don't exist), while when executed under command line, they are not null and even take other arguments values, for instance:
Rscript script.R -i file.txt -o output_test -b 1000 -p 40 --firstRegionName "Selection" --signalName ""
$input
[1] "file.txt"
$output
[1] "output_test"
$bootstraps
[1] 1000
$bootstrapsCI
[1] 0.95
$CPU
[1] 40
$wilcoxStartBin
[1] "output_test"
$wilcoxEndBin
[1] "output_test"
$wilcoxThreshold
[1] "output_test"
$firstRegionName
[1] "Selection"
$secondRegionName
[1] "Region2"
$bootPlotWidth
[1] 1000
$bootPlotHeight
[1] 1000
$bootPlotColors
[1] 1000
$wilcoxPlotWidth
[1] "output_test"
$wilcoxPlotHeight
[1] "output_test"
$signalName
[1] "A"
$help
[1] FALSE
When just executing script.R
without any arguments, then opt
has the correct default values and the default NULL are correctly assigned.
$bootstraps
[1] 1000
$bootstrapsCI
[1] 0.95
$CPU
[1] 4
$wilcoxThreshold
[1] 0.05
$firstRegionName
[1] "Region1"
$secondRegionName
[1] "Region2"
$bootPlotWidth
[1] 6
$bootPlotHeight
[1] 3.7
$wilcoxPlotWidth
[1] 4.6
$wilcoxPlotHeight
[1] 3.7
$signalName
[1] "Genomic signal"
$help
[1] FALSE
Hello,
I'm opening this issue here, but it might just as well be opened at the r-argparse-repo.
New users might need guidance on when to use r-argparse or r-optparse. It is unclear which package is superior to the other and the use cases are identical. From what I understood, r-argparse uses the python package as a backend, so it directly benefits from developments there, but therefore carries additional dependencies. r-optparse has more downloads but that might be for historical reasons and recommendations.
r-argparse appears to be more powerful (but maybe a bit more hurdlesome), due to its python-argparse backbone. Personally, I need support for multiple arguments (and I found issues #36, #22 discussing this and stating that it's missing), so I decided to go with r-argparse.
Note that this was only a very brief evaluation, but one could go into more detail here. Maybe putting a similar document to mine in both or at least one of the repos' READMEs might help users make the right decision. A feature comparison (maybe as a table) might be helpful, too.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.