[R] wrapping mle()

Luke Tierney luke at stat.uiowa.edu
Wed Jan 3 17:03:23 CET 2007


On Sat, 30 Dec 2006, Gabor Grothendieck wrote:

> That has two disadvantages:
>
> (1) it only works if the user is defining ll himself; however, if the
> user is getting
> ll from somewhere else then its not applicable since the user no
> longer controls its
> scope whereas resetting the environment method still works

In that case surgery on environments is even worse: There is no
reliable way to know which variables in an arbitrary function body
might benefit from having values provided though environment surgery
and which ones definitely should not be messed with this in this
way. Brian's reply in this thread is related to this.  The reliable
way to provide data for variables in a function body is to make those
variables arguments in an appropriate function -- that is what the
nested function approach does.  In situations like these careful use
of ... arguments is another option but this can be tricky to get
right.  It is far superior to environment surgery though.

> (2) its "cleaner" for the developer but harder for the user who is now
> forced into
> a more complicated construct, i.e. the nested double function construct

Aside from the fact that the S language philosophy is to blur the
user/developer distinction this really does not make sense. Nested
functions like these are a simple idea that is basic to all modern
function-oriented languages.  (It even exists in languages like Pascal
for downward-only function arguments.) It is an idea that can be useful
for anyone who writes functions in R.  Environment surgery in contrast
is messy and complex and essentially impossible to get right.  If you
want to do this in the privacy of your own code that is fine, but
please don't encourage others to go down this path.

Best,

luke


>
> By the way, here is one additional solution using the proto package that
> avoids explicitly resetting of the environment in favor implicitly setting 
> it.
> A new proto object is created which to hold FUN and since proto methods have
> their object as their scope, their environment is implicitly reset:
>
> library(proto)
> library(stats4)
> ll <- function(ymax=15, xhalf=6) {
> -sum(stats::dpois(y, lambda=ymax/(1+x/xhalf), log=TRUE))
> }
> fit.mle <- function(FUN, x, y)
> mle(proto(FUN = match.fun(FUN))[["FUN"]], method="L-BFGS-B", lower=c(0, 0))
> fit.mle("ll", x=0:10, y=c(26, 17, 13, 12, 20, 5, 9, 8, 5, 4, 8))
>
>
>
>
>
>
> On 12/30/06, Luke Tierney <luke at stat.uiowa.edu> wrote:
>> It is much cleaner to do this sort of thing with lexical scope.  For
>> example,
>>
>>     mkll <- function(x, y) {
>>        function(ymax=15, xhalf=6) {
>>           -sum(stats::dpois(y, lambda=ymax/(1+x/xhalf), log=TRUE))
>>        }
>>     }
>> 
>> creates a log-likelihood likelyhood function for data x,y that can
>> then be used by
>>
>>     fit.mle <- function(mkfun, x, y) {
>>         loglik.fun <- mkfun(x, y)
>>         mle(loglik.fun, method="L-BFGS-B", lower=c(0, 0))
>>     }
>> 
>> as in
>> 
>>
>>     > fit.mle(mkll, x=0:10, y=c(26, 17, 13, 12, 20, 5, 9, 8, 5, 4, 8))
>>
>>     Call:
>>     mle(minuslogl = loglik.fun, method = "L-BFGS-B", lower = c(0,
>>         0))
>>
>>     Coefficients:
>>          ymax     xhalf
>>     24.999420  3.055779
>> 
>> It is not clear why you want to be able to pass ll as a character
>> string or why you want to assume that the thing passed in will refer
>> to variables named 'x' and 'y', both usually bad ideas, so this
>> specific approach may not apply, but something variant should.
>> 
>> The ability to use environment(f)<-env to change the environment of a
>> function is one of the most dubious language features of R (maybe the
>> most dubious, though there are a couple of other strong contenders)
>> and should not be used except in very rare circumstances.
>> 
>> Best,
>> 
>> luke
>> 
>> On Sat, 30 Dec 2006, Gabor Grothendieck wrote:
>> 
>> > Add the line marked ### so that the environment of loglik.fun is reset to
>> > the environment within fit.mle so that it can find y there:
>> >
>> > library(stats4)
>> > ll <- function(ymax=15, xhalf=6) {
>> >   -sum(stats::dpois(y, lambda=ymax/(1+x/xhalf), log=TRUE))
>> > }
>> > fit.mle <- function(FUN, x, y) {
>> >   loglik.fun <- match.fun(FUN)
>> >   environment(loglik.fun) <- environment() ###
>> >   mle(loglik.fun, method="L-BFGS-B", lower=c(0, 0))
>> > }
>> > fit.mle("ll", x=0:10, y=c(26, 17, 13, 12, 20, 5, 9, 8, 5, 4, 8))
>> >
>> >
>> >
>> > On 12/30/06, Sebastian P. Luque <spluque at gmail.com> wrote:
>> >> Hi,
>> >>
>> >> How can we set the environment for the minuslog function in mle()?  The
>> >> call in this code fails because the "ll" function cannot find the object
>> >> 'y'.  Modifying from the example in ?mle:
>> >>
>> >>
>> >> library(stats4)
>> >> ll <- function(ymax=15, xhalf=6) {
>> >>    -sum(stats::dpois(y, lambda=ymax/(1+x/xhalf), log=TRUE))
>> >> }
>> >> fit.mle <- function(FUN, x, y) {
>> >>    loglik.fun <- match.fun(FUN)
>> >>    mle(loglik.fun, method="L-BFGS-B", lower=c(0, 0))
>> >> }
>> >> fit.mle("ll", x=0:10, y=c(26, 17, 13, 12, 20, 5, 9, 8, 5, 4, 8))
>> >>
>> >>
>> >> How should "fit.mle" be constructed so that "ll" works on the 
>> appropriate
>> >> environment?  Thanks in advance for any advice on this.
>> >>
>> >>
>> >> --
>> >> Seb
>> >>
>> >> ______________________________________________
>> >> R-help at stat.math.ethz.ch 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.
>> >>
>> >
>> > ______________________________________________
>> > R-help at stat.math.ethz.ch 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.
>> >
>> 
>> --
>> Luke Tierney
>> Chair, Statistics and Actuarial Science
>> Ralph E. Wareham Professor of Mathematical Sciences
>> University of Iowa                  Phone:             319-335-3386
>> Department of Statistics and        Fax:               319-335-3017
>>    Actuarial Science
>> 241 Schaeffer Hall                  email:      luke at stat.uiowa.edu
>> Iowa City, IA 52242                 WWW:  http://www.stat.uiowa.edu
>> 
>

-- 
Luke Tierney
Chair, Statistics and Actuarial Science
Ralph E. Wareham Professor of Mathematical Sciences
University of Iowa                  Phone:             319-335-3386
Department of Statistics and        Fax:               319-335-3017
    Actuarial Science
241 Schaeffer Hall                  email:      luke at stat.uiowa.edu
Iowa City, IA 52242                 WWW:  http://www.stat.uiowa.edu



More information about the R-help mailing list