Re: [R] wrapping mle()

From: Luke Tierney <luke_at_stat.uiowa.edu>
Date: Wed 03 Jan 2007 - 16:03:23 GMT

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@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@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@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@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@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@stat.uiowa.edu
Iowa City, IA 52242                 WWW:  http://www.stat.uiowa.edu

______________________________________________
R-help@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.
Received on Thu Jan 04 12:29:01 2007

Archive maintained by Robert King, hosted by the discipline of statistics at the University of Newcastle, Australia.
Archive generated by hypermail 2.1.8, at Thu 04 Jan 2007 - 01:30:28 GMT.

Mailing list information is available at https://stat.ethz.ch/mailman/listinfo/r-help. Please read the posting guide before posting to the list.