Search code examples
rellipsisoptional-arguments

How to deal with ellipsis (...) in the presence of optional arguments?


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:

  1. assigns default value, i.e. 5, to n.restarts as an optional argument
  2. 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


Solution

  • 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