如何将未知参数集传递给 R 函数
How pass unknown set of parameters to R function
我有一个类似
的函数
myfunc <- function(x, y=x){
x+y
}
如果没有将 y 传递给函数,那么(显然)会将 y 的值默认为 x。
现在,我正在使用 optparse
读取一些命令行参数到调用 myfunc
.
的脚本
# myscript.R
option_list <- list(
make_option(c("--x"), type="numeric"),
make_option(c("--y"), type="numeric")
)
print(myfunc(opt$x, opt$y))
上面代码的问题是,它强制用户为 y 提供一个值(否则会抛出错误)。相反,我想调用 myfunc
使用所有且仅使用用户提供的参数。我怎样才能以最优雅、可扩展、可概括的方式实现这一目标?
注意 - 对于那些熟悉 Python 的人,我想我想使用 opt
.
中的任何值做一些类似于字典解包的事情
如果您有来自 optparse
的参数的命名列表并希望提供给函数,您可以使用 do.call
:
# Provide x and y
opts <- list(x=2, y=3)
do.call(myfunc, opts)
# [1] 5
# Provide only x
opts <- list(x=2)
do.call(myfunc, opts)
# [1] 4
如您所见,这基本上是 Python 的 "dictionary unpacking"/"splatting"。
然后,您可以使用 optparse
获取 x 和 y 的值,使 y 成为命令行上的可选输入:
# optparse.R
library(optparse)
option_list <- list(make_option("--x", type="integer", default=0),
make_option("--y", type="integer"))
opt <- parse_args(OptionParser(option_list=option_list))
myfunc <- function(x, y=x) x+y
do.call(myfunc, opt[names(opt) %in% c("x", "y")])
# > Rscript optparse.R --x=2 --y=3
# [1] 5
# > Rscript optparse.R --x=2
# [1] 4
通过使用被调用的 R 函数来计算 y 的默认值而不是命令行解析器,可以很容易地为 y 设置更复杂的默认值,例如 y=min(0, x)
.
# optparse.R
library(optparse)
option_list <- list(make_option("--x", type="integer", default=0),
make_option("--y", type="integer"))
opt <- parse_args(OptionParser(option_list=option_list))
myfunc <- function(x, y=min(0, x)) x+y
do.call(myfunc, opt[names(opt) %in% c("x", "y")])
# > Rscript optparse.R --x=-2
# [1] -4
# > Rscript optparse.R --x=2
# [1] 2
我更喜欢更新的 docopt over optparse,因为我发现 docopt 是
- 更易于使用(见下文)
- 广泛适用于多种语言,请参阅 docopt.org
这里是一个最小的示例,它还提供了默认值,这是您在这里关心的问题。先上代码:
#!/usr/bin/Rscript
library(methods) # as Rscript does not load it
library(docopt)
## simple helper function
myfunc <- function(x, y) as.numeric(x) + as.numeric(y)
doc <- "Usage: myscript [-x x] [-y y]
-x x Numeric value for x [default: 0.0]
-y y Numeric value for y [default: -7.89]"
opt <- docopt(doc)
print(myfunc(opt$x, opt$y))
那么用法:
edd@max:/tmp$ ./myscript.R --help
Usage: myscript [-x x] [-y y]
-x x Numeric value for x [default: 0.0]
-y y Numeric value for y [default: -7.89]
edd@max:/tmp$ ./myscript.R
[1] -7.89
edd@max:/tmp$ ./myscript.R -y 40 -x 2
[1] 42
edd@max:/tmp$
请注意,我们必须对值使用 as.numeric()
,因为 docopt 不做的一件事是保证/强制执行类型。
我有一个类似
的函数myfunc <- function(x, y=x){
x+y
}
如果没有将 y 传递给函数,那么(显然)会将 y 的值默认为 x。
现在,我正在使用 optparse
读取一些命令行参数到调用 myfunc
.
# myscript.R
option_list <- list(
make_option(c("--x"), type="numeric"),
make_option(c("--y"), type="numeric")
)
print(myfunc(opt$x, opt$y))
上面代码的问题是,它强制用户为 y 提供一个值(否则会抛出错误)。相反,我想调用 myfunc
使用所有且仅使用用户提供的参数。我怎样才能以最优雅、可扩展、可概括的方式实现这一目标?
注意 - 对于那些熟悉 Python 的人,我想我想使用 opt
.
如果您有来自 optparse
的参数的命名列表并希望提供给函数,您可以使用 do.call
:
# Provide x and y
opts <- list(x=2, y=3)
do.call(myfunc, opts)
# [1] 5
# Provide only x
opts <- list(x=2)
do.call(myfunc, opts)
# [1] 4
如您所见,这基本上是 Python 的 "dictionary unpacking"/"splatting"。
然后,您可以使用 optparse
获取 x 和 y 的值,使 y 成为命令行上的可选输入:
# optparse.R
library(optparse)
option_list <- list(make_option("--x", type="integer", default=0),
make_option("--y", type="integer"))
opt <- parse_args(OptionParser(option_list=option_list))
myfunc <- function(x, y=x) x+y
do.call(myfunc, opt[names(opt) %in% c("x", "y")])
# > Rscript optparse.R --x=2 --y=3
# [1] 5
# > Rscript optparse.R --x=2
# [1] 4
通过使用被调用的 R 函数来计算 y 的默认值而不是命令行解析器,可以很容易地为 y 设置更复杂的默认值,例如 y=min(0, x)
.
# optparse.R
library(optparse)
option_list <- list(make_option("--x", type="integer", default=0),
make_option("--y", type="integer"))
opt <- parse_args(OptionParser(option_list=option_list))
myfunc <- function(x, y=min(0, x)) x+y
do.call(myfunc, opt[names(opt) %in% c("x", "y")])
# > Rscript optparse.R --x=-2
# [1] -4
# > Rscript optparse.R --x=2
# [1] 2
我更喜欢更新的 docopt over optparse,因为我发现 docopt 是
- 更易于使用(见下文)
- 广泛适用于多种语言,请参阅 docopt.org
这里是一个最小的示例,它还提供了默认值,这是您在这里关心的问题。先上代码:
#!/usr/bin/Rscript
library(methods) # as Rscript does not load it
library(docopt)
## simple helper function
myfunc <- function(x, y) as.numeric(x) + as.numeric(y)
doc <- "Usage: myscript [-x x] [-y y]
-x x Numeric value for x [default: 0.0]
-y y Numeric value for y [default: -7.89]"
opt <- docopt(doc)
print(myfunc(opt$x, opt$y))
那么用法:
edd@max:/tmp$ ./myscript.R --help
Usage: myscript [-x x] [-y y]
-x x Numeric value for x [default: 0.0]
-y y Numeric value for y [default: -7.89]
edd@max:/tmp$ ./myscript.R
[1] -7.89
edd@max:/tmp$ ./myscript.R -y 40 -x 2
[1] 42
edd@max:/tmp$
请注意,我们必须对值使用 as.numeric()
,因为 docopt 不做的一件事是保证/强制执行类型。