I'm looking for advice on manipulating parameters that are going to be passed through to another function. Specifically, I am working on my version of "mle", which is a wrapper for optim (among other optimizers). I would prefer not to replicate the entire argument list of optim(), so I'm using ... to pass extra arguments through. However: the starting values are specified as a list, which means that users can potentially specify them in any order (or at least that's the way it works now -- one solution to the problem I'm about to state is to insist that they specify the parameters in the same order as they are given in the arguments of the objective function). However, there are other arguments (lower, upper, control$parscale, control$ndeps) that should all be in the same order as the objective function definition by the time they get to optim()). I can think of a few solutions: (1) make the user specify them all in the right order (ugh) (2) add all of them as explicit parameters to my function so that I can rearrange them appropriately (ugh) (3) mess with the ... argument before it gets passed through to optim (impossible?) (4) capture ... as arglist <- list(...), manipulate the arguments as necessary, then pass them along to optim as do.call("optim",arglist) (ugh but maybe the best solution?) any thoughts? thanks Ben Bolker -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 252 bytes Desc: OpenPGP digital signature URL: <https://stat.ethz.ch/pipermail/r-devel/attachments/20080813/e84ce625/attachment.bin>
Ben Bolker wrote:> > I'm looking for advice on manipulating parameters that > are going to be passed through to another function. > > Specifically, I am working on my version of "mle", > which is a wrapper for optim (among other optimizers). > I would prefer not to replicate the entire argument > list of optim(), so I'm using ... to pass extra arguments > through. > > However: > the starting values are specified as a list, > which means that users can potentially specify them > in any order (or at least that's the way it works > now -- one solution to the problem I'm about to state > is to insist that they specify the parameters in the > same order as they are given in the arguments of > the objective function). > However, there are other arguments (lower, upper, > control$parscale, control$ndeps) that should all > be in the same order as the objective function > definition by the time they get to optim()). I can > think of a few solutions: > > (1) make the user specify them all in the right order (ugh) > (2) add all of them as explicit parameters to my function > so that I can rearrange them appropriately (ugh) > (3) mess with the ... argument before it gets passed > through to optim (impossible?) > (4) capture ... as arglist <- list(...), manipulate the arguments > as necessary, then pass them along to optim as > do.call("optim",arglist) (ugh but maybe the best solution?) > > any thoughts?here's my two cents: - require names on parameters, rather than order - construct calls and use eval() rather than do.call() (then you can manipulate list(...) without the ugh factor of do.call() -- though is do.call() any different to eval() in R? -- I know in S-PLUS that the use of do.call() can completely blow out memory usage) - to avoid manually duplicating arg lists, use constructs like names(formals(optim)) and pmatch to find args that below to the optimizer function vs the objective function -- Tony Plate> > thanks > > Ben Bolker > > > ------------------------------------------------------------------------ > > ______________________________________________ > R-devel at r-project.org mailing list > https://stat.ethz.ch/mailman/listinfo/r-devel >
If I understand it correctly, one way would be to define a function to specify the default options/arguments in the required order. For example,> mle.options <- function(method = "BFGS", lower = 0, upper = Inf,hessian=FALSE) + list(method=method, lower=lower, upper=upper, hessian=hessian)> mle.options()$method [1] "BFGS" $lower [1] 0 $upper [1] Inf $hessian [1] FALSE And the user can specify only the parameters that need non-default values:> mle.options(method="CG")$method [1] "CG" $lower [1] 0 $upper [1] Inf $hessian [1] FALSE A similar function can be defined for the control parameters of optim. Then all you need in the mle wrapper is: mle <- function(X, Y, optim.meth=mle.options(), optim.control=mle.control(), ...) { # preparatory steps optim(par, fn, method=optim.meth$method, lower=optim.meth$lower, upper=optim.meth$upper, hessian=optim.meth$hessian, control = optim.control(), ...) # more stuff } Hope this helps. -Christos> -----Original Message----- > From: r-devel-bounces at r-project.org > [mailto:r-devel-bounces at r-project.org] On Behalf Of Ben Bolker > Sent: Wednesday, August 13, 2008 11:46 AM > To: r-devel at r-project.org > Subject: [Rd] messing with ... > > > I'm looking for advice on manipulating parameters that are > going to be passed through to another function. > > Specifically, I am working on my version of "mle", which > is a wrapper for optim (among other optimizers). > I would prefer not to replicate the entire argument list of > optim(), so I'm using ... to pass extra arguments through. > > However: > the starting values are specified as a list, which means > that users can potentially specify them in any order (or at > least that's the way it works now -- one solution to the > problem I'm about to state is to insist that they specify the > parameters in the same order as they are given in the > arguments of the objective function). > However, there are other arguments (lower, upper, > control$parscale, control$ndeps) that should all be in the > same order as the objective function definition by the time > they get to optim()). I can think of a few solutions: > > (1) make the user specify them all in the right order (ugh) > (2) add all of them as explicit parameters to my function > so that I can rearrange them appropriately (ugh) > (3) mess with the ... argument before it gets passed > through to optim (impossible?) > (4) capture ... as arglist <- list(...), manipulate the > arguments as necessary, then pass them along to optim as > do.call("optim",arglist) (ugh but maybe the best solution?) > > any thoughts? > > thanks > > Ben Bolker > > >