可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
I have a problem with ellipsis when I use optional arguments in my function definition. To clarify, I define following functions:
func1 <- function (x) (x-2)^2 func3 <- function (fun, arg.curve.user){ arg.curve.user$expr <- substitute(func1) arg.curve.default <- list(col = "blue", n = 1000, main = "This is a test") arg.curve <- modifyList (arg.curve.default, arg.curve.user) do.call("curve", arg.curve) } # optimizes func1 and call func2 to plot func1 func2 <- function (lb, ub, n.restarts = 5, n.sim = 10, ...){ arg.curve.user <- as.list(substitute(list(...))) output <- gosolnp(fun = func1, LB = lb, UB = ub, n.restarts = n.restarts, n.sim = n.sim)$par func3(fun = func1, arg.curve.user = arg.curve.user) return(output) }
By calling func2, func1 is optimized and also plotted through a func3 call (package Rsolnp is required).
func2 ( lb = 0, ub = 8, n.restarts = 5, n.sim = 10, n = 200, from = 0, to = 8)
But suppose a user misspells n.restarts
and writes nrestarts
:
func2 ( lb = 0, ub = 8, nrestarts = 5, n.sim = 10, n = 200, from = 0, to = 8)
In this case, I expects R to implement the following plans to deal with absence of n.restarts
:
- assigns default value, i.e. 5, to n.restarts as an optional argument
- declares a warning at the end: "nrestarts" is not a graphical parameter
But this does not happen and R assigns value of n (200) to n.restarts instead!!
Can anyone help me to fix this problem?
Many thanks
回答1:
It is partial matching the n
argument to n.restarts
when one is not supplied by the user. Instead, and contrary to the advice of @Andrie (which will work, of course), there is a mechanism that allows you to continue in the manner you have with an argument n
and and argument n.restarts
. The trick is to place arguments you want to match exactly after the ...
.
func2 <- function (lb, ub, ..., n.restarts = 5, n.sim = 10){ writeLines(paste("Value of `n.restarts` is", n.restarts)) arg.curve.user <- as.list(substitute(list(...))) output <- gosolnp(fun = func1, LB = lb, UB = ub, n.restarts = n.restarts, n.sim = n.sim)$par func3(fun = func1, arg.curve.user = arg.curve.user) output }
In use this gives:
> func2 (lb = 0, ub = 8, n.restarts = 2, n.sim = 10, n = 200, + from = 0, to = 8) Value of `n.restarts` is 2 <---- Here! Iter: 1 fn: 6.926e-15 Pars: 2.00000 Iter: 2 fn: 2.501e-15 Pars: 2.00000 solnp--> Completed in 2 iterations Iter: 1 fn: 8.336e-16 Pars: 2.00000 Iter: 2 fn: 8.336e-16 Pars: 2.00000 solnp--> Completed in 2 iterations [1] 2 > func2 (lb = 0, ub = 8, nrestarts = 2, n.sim = 10, n = 200, + from = 0, to = 8) Value of `n.restarts` is 5 <---- Here! Default Iter: 1 fn: 2.83e-15 Pars: 2.00000 Iter: 2 fn: 2.5e-15 Pars: 2.00000 solnp--> Completed in 2 iterations Iter: 1 fn: 2.037e-15 Pars: 2.00000 Iter: 2 fn: 2.037e-15 Pars: 2.00000 solnp--> Completed in 2 iterations Iter: 1 fn: 1.087e-15 Pars: 2.00000 Iter: 2 fn: 1.087e-15 Pars: 2.00000 solnp--> Completed in 2 iterations Iter: 1 fn: 8.558e-16 Pars: 2.00000 Iter: 2 fn: 8.558e-16 Pars: 2.00000 solnp--> Completed in 2 iterations Iter: 1 fn: 7.147e-16 Pars: 2.00000 Iter: 2 fn: 7.147e-16 Pars: 2.00000 solnp--> Completed in 2 iterations [1] 2 Warning messages: 1: In plot.window(...) : "nrestarts" is not a graphical parameter 2: In plot.xy(xy, type, ...) : "nrestarts" is not a graphical parameter 3: In axis(side = side, at = at, labels = labels, ...) : "nrestarts" is not a graphical parameter 4: In axis(side = side, at = at, labels = labels, ...) : "nrestarts" is not a graphical parameter 5: In box(...) : "nrestarts" is not a graphical parameter 6: In title(...) : "nrestarts" is not a graphical parameter
回答2:
If you stick with regular argument evaluation you are more likely to get warnings off the bat. Again, you don't need to use special evaluation to get the behaviour that you want. Using non-standard evaluation is a bad idea as you are unlikely to exactly reproduce R's default behaviour, causing subtle bugs for you and your users.
library(Rsolnp) func1 <- function (x) (x-2)^2 func3 <- function (fun, col = "blue", n = 1000, main = "This is a test", ...){ curve(func1, ..., n = n, col = col, main = main) } # optimizes func1 and call func2 to plot func1 func2 <- function (lb, ub, n.restarts = 5, n.sim = 10, ...){ output <- gosolnp(fun = func1, LB = lb, UB = ub, n.restarts = n.restarts, n.sim = n.sim)$par func3(fun = func1, ...) return(output) }
Then when you run:
func2 ( lb = 0, ub = 8, nrestarts = 5, n.sim = 10, n = 200, from = 0, to = 8)
you get warnings along the lines of
Warning messages: 1: In plot.window(...) : "nrestarts" is not a graphical parameter 2: In plot.xy(xy, type, ...) : "nrestarts" is not a graphical parameter 3: In axis(side = side, at = at, labels = labels, ...) : "nrestarts" is not a graphical parameter 4: In axis(side = side, at = at, labels = labels, ...) : "nrestarts" is not a graphical parameter 5: In box(...) : "nrestarts" is not a graphical parameter 6: In title(...) : "nrestarts" is not a graphical parameter