如何在存在可选参数的情况下处理省略号(...)?

时间:2013-01-15 09:10:44

标签: r ellipsis optional-arguments

当我在函数定义中使用可选参数时,省略号有问题。为了澄清,我定义了以下功能:

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)
}

通过调用func2,func1已经过优化,并且还通过func3调用绘制(需要包 Rsolnp )。

func2 ( lb = 0, ub = 8, n.restarts = 5, n.sim = 10, n = 200, from = 0, to = 8)

但假设用户拼错了n.restarts并写了nrestarts

func2 ( lb = 0, ub = 8, nrestarts = 5, n.sim = 10, n = 200, from = 0, to = 8)

在这种情况下,我希望R实施以下计划来处理n.restarts的缺席:

  1. 将默认值(即5)指定为n.restarts作为可选参数
  2. 在结尾处声明警告:“nrestarts”不是图形参数
  3. 但这不会发生, R会将n(200)的值分配给n.restarts 而不是!!

    有人可以帮我解决这个问题吗?

    非常感谢

2 个答案:

答案 0 :(得分:8)

n参数未被用户提供时,n.restarts参数与n部分匹配。相反,与@Andrie(当然会有效)的建议相反,有一种机制允许您以参数n.restarts和参数...的方式继续。诀窍是在 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 } 之后放置想要匹配完全 的参数。

> 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

在使用中,这给出了:

{{1}}

答案 1 :(得分:2)

如果您坚持使用常规参数评估,您更有可能获得警告。同样,您不需要使用特殊评估来获得所需的行为。使用非标准评估是一个坏主意,因为您不太可能完全重现R的默认行为,从而为您和您的用户带来微妙的错误。

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)
}

然后当你跑:

func2 ( lb = 0, ub = 8, nrestarts = 5, n.sim = 10, n = 200, from = 0, to = 8)

你会收到警告

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