Re: R-beta: nlm

Thomas Lumley (thomas@biostat.washington.edu)
Sun, 8 Jun 1997 14:01:39 -0700 (PDT)


Date: Sun, 8 Jun 1997 14:01:39 -0700 (PDT)
From: Thomas Lumley <thomas@biostat.washington.edu>
To: Ennapadam Venkatraman <VENKAT@biosta.mskcc.org>
Subject: Re: R-beta: nlm
In-Reply-To: <199706022138.XAA03770@hypatia.math.ethz.ch>

On 6 Jun 1997, Ennapadam Venkatraman wrote:

> I am trying to use the function "nlm" to find the mle. I want to use a
> generic function for the likelihood which would require me to use both the
> parameters and the data as arguments. But nlm requires the function to
> have only the parameters as arguments for this function (see example below). 
> 
>    > testfun <- function(x,y) sum((x-y)^2) # x - parameters, y - data
>    > nlm(tfun,0)
>    Error: Argument "y" is missing, with no default
> 
> Thus the problem I have is as follows:
> 
> llkfun  --  generic function to calculate the likelihood 
>                 for given data and parameters
> mlefun  --  function to evaluate mle for a given dataset which calls
>                 nlm(llkfun,...) 
> 
> I tried using "get", "sys.???" etc in 'llkfun' so that it can be written as
> just a function of parameters.  But it doesn't seem to work, always giving me
> an error message -- data not found. (It works if I just call 'llkfun' inside
> 'mlefun' -- only the nlm step doesn't).  So I want data defined in the frame 
> for 'mlefun' to be passed down to 'llkfun' through 'nlm'.


I think this is possible by messing with environments a bit:
Consider this simple example
R> testfun
function (x) 
x + y
R> wrapfun2
function (z, fun) 
{
        y <- z
        environment(fun) <- sys.frame(sys.nframe())
        fun(2)
}
R> testfun(2)
Error: Object "y" not found
R> wrapfun2(2,testfun)
[1] 4

The line environment(fun) <- sys.frame(sys.nframe()) sets the environment
of the function to be the internal environment of wrapfun2(), in which y
is defined. 

One way to use this is to define a wrapper for nlm

nlm.env<-function(fun,...,env=NULL){
	if (!is.null(env) && is.environment(env)) 
		environment(fun)<-env
	nlm(fun,...)
	}

Then:
R>afun
function (x) 
(x - y)^2
R>badfun
function (z, fun) 
{
        y <- z
        nlm(fun, 1)
}
R>goodfun
function (z, fun) 
{
        y <- z
        env <- sys.frame(sys.nframe())
        nlm.env(fun, 1, env = env)
}
R>badfun(2,afun)
Error: Object "y" not found
R>goodfun(2,afun)
$minimum
[1] 0

$estimate
[1] 2

$gradient
[1] 0

$code
[1] 1



Thomas Lumley
-----------------------------------------------------+------
Biostatistics		: "Never attribute to malice what  :
Uni of Washington	:  can be adequately explained by  :
Box 357232		:  incompetence" - Hanlon's Razor  :
Seattle WA 98195-7232	:				   :
------------------------------------------------------------

=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
r-help mailing list -- Read http://www.ci.tuwien.ac.at/~hornik/R/R-FAQ.html
Send "info", "help", or "[un]subscribe"
(in the "body", not the subject !)  To: r-help-request@stat.math.ethz.ch
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=