[R] optim() argument scoping: passing parameter values into user's subfunction
Ben Bolker
bolker at ufl.edu
Wed Sep 9 04:29:09 CEST 2009
Szumiloski, John wrote:
>
> Dear useRs,
>
> I have a complicated function to be optimized with optim(), and whose
> parameters are passed to another function within its evaluation. This
> function allows for the parameters to enter as arguments to various
> probability distribution functions.
>
> However, I am violating some scoping convention, as somewhere within the
> hierarchy of calls a variable is not visible. I will give a genericized
> example here.
>
>> myFxn <- function(parms, Y, phi, <other args>) {<body of function>}
> ### I want to optimize this over its first argument
>
>> optim(par=<numeric(>2)>, fn=myFxn, ### end of named args, next are
> all in "..."
> Y=<data>, <other args>,
> phi=function(r) pnorm(r, mean=parms[2], sd=parms[1])
> )
> Error in pnorm(r, mean = parms[2], sd = parms[1]) :
> object 'parms' not found
>> debugger() ## options(error=expression(dump.frames())) in
> .RProfile
> Message: Error in pnorm(r, mean = parms[2], sd = parms[1]) :
> object 'parms' not found
> Available environments had calls:
> 1: optim(par = <numeric(>2)>, fn = myFxn, Y=<data>, <other args>, ..
> 2: function (par)
> 3: fn(par, ...)
> 4: ifelse(<logical vector>, phi(Y), <other stuff within myFxn>
> 5: phi(Y)
> 6: pnorm(r, mean = parms[2], sd = parms[1])
>
> Now, when using the debugger in environments 1 and 2, I can see the
> value of 'par' correctly. I cannot access environment 4 as it just
> returns the original error message. Trying to access environment 3
> gives the (to me) cryptic 'Error in get(.obj, envir =
> dump[[.selection]]) : argument "..." is missing, with no default' and
> returns to the top level without debugging.
>
> I will try to explain to the best of my ability what I think is
> happening here. Environments 2 and 3 are from the first lines of
> optim(), where it is building an internal function to evaluate the
> candidate parameter values. When accessing environment 3, it seems like
> when it fills out the "..." argument of fn(), it is passing
> phi=function(r) pnorm(r, mean=parms[2], sd=parms[1]) but upon trying to
> evaluate the variable 'parms', it cannot see it in the search path.
> When actually running the original call, 'parms' is apparently not
> evaluated yet, but is once the pnorm call is hit. It appears the
> 'parms' variable is being evaluated before the fn(par) is evaluated into
> myFxn(parms=par).
>
> A point which is probably, but not certainly, irrelevant: myFxn() has
> "..." as its final argument, so as to pass tuning arguments to
> integrate(). The function being integrated contains phi(), as well as
> other stuff, of a dummy variable. The calls in the debugging tree,
> however, are *not* those involving integrate().
>
> It would probably be possible to include some
> substitute/eval/as.name/etc. constructions within the function myFxn, in
> order to avoid this problem, but as myFxn already involves numeric
> integrations whose integrand involves the optimized parameters
> themselves, computing on the language at each step of the optimization
> seems like a bad idea.
>
> My question: is there a straightforward and efficient way of
> constructing this function and optimizing it with optim(), allowing for
> the argument phi to pass an arbitrary distribution function whose
> parameters are the global ones being optimized? In particular, in the
> third environment of the debugger tree, is there a way to force the
> fn(par, ...) ----> myFxn(parms=par, ...) evaluation before the "..." get
> evaluated?
>
> Thanks, John
>
> John Szumiloski, Ph.D.
>
> Senior Biometrician
> Biometrics Research
> WP53B-120
> Merck Research Laboratories
> P.O. Box 0004
> West Point, PA 19486-0004
>
>> (215) 652-7346 (PH)
>> (215) 993-1835 (FAX)
>>
>>
> #################################################
> #### obligatory session info
> ####
> #### Windows XP 2002 sp3, customized by corporate IT
>
>> version
> _
> platform i386-pc-mingw32
> arch i386
> os mingw32
> system i386, mingw32
> status Patched
> major 2
> minor 9.2
> year 2009
> month 09
> day 05
> svn rev 49600
> language R
> version.string R version 2.9.2 Patched (2009-09-05 r49600)
>
>> search()
> [1] ".GlobalEnv" "package:geometry" "package:datasets"
> "<mylib1>" "<mylib2>"
> [6] "package:VGAM" "package:stats4" "package:Design"
> "package:Hmisc" "package:boot"
> [11] "package:splines" "package:MASS" "package:nnet"
> "package:utils" "package:stats"
> [16] "package:graphics" "package:grDevices" "<mylib3>"
> "<mylib4>" "<mylib5>"
> [21] "<mylib6>" "package:methods" "Autoloads"
> "package:base"
>
> Notice: This e-mail message, together with any attachme...{{dropped:15}}
>
> ______________________________________________
> R-help at r-project.org mailing list
> https://stat.ethz.ch/mailman/listinfo/r-help
> PLEASE do read the posting guide
> http://www.R-project.org/posting-guide.html
> and provide commented, minimal, self-contained, reproducible code.
>
>
Will the following tweak work for you? It's not very realistic
but it might solve the problem.
## new version
myFxn <- function(parms, Y,
phi=function(r) pnorm(r, mean=parms[2], sd=parms[1]),
X) {
phi(1)
sum((Y-(parms[1]+parms[2]*X))^2)
}
set.seed(1001)
X = 1:10
Y = 1+2*X+rnorm(10)
optim(par=c(1,2), fn=myFxn,
Y=Y, X=X)
### original
myFxn2 <- function(parms, Y,
phi,
X) {
phi(1)
sum((Y-(parms[1]+parms[2]*X))^2)
}
set.seed(1001)
X = 1:10
Y = 1+2*X+rnorm(10)
optim(par=c(1,2), fn=myFxn2,
phi = function(r) pnorm(r, mean=parms[2], sd=parms[1]),
Y=Y, X=X)
--
View this message in context: http://www.nabble.com/optim%28%29-argument-scoping%3A-passing-parameter-values-into-user%27s-subfunction-tp25350121p25357520.html
Sent from the R help mailing list archive at Nabble.com.
More information about the R-help
mailing list