[R] passing variable to formula environment

Sundar Dorai-Raj sundar.dorai-raj at pdf.com
Wed Aug 3 21:11:08 CEST 2005



Eric Archer wrote:
> List gurus,
> 
> I'm trying to code a Gompertz growth curve function as part of a larger 
> project and have run across a problem due to my ignorance of 
> environments. Some sample data and the function are as follows:
> 
> growth <- data.frame(age = c(1.92, 3, 5.83, 3.17, 15.5, 1.17, 5.58, 
> 13.33, 14.29, 5.83, 13.79, 6.33, 13.75, 16.83, 13, 11.67, 0.25, 1.73, 
> 9.46, 5.67), length = c(157, 165, 179, 171, 195, 135, 179, 193, 194, 
> 186, 196, 186, 210, 200, 189, 194, 106, 161, 188, 159))
> 
> # return gompertz fit
> Gompertz <- function(data,Xintercept,Lzero,start) {
>   gomp <- formula(length ~ Lzero * exp(k * (1 - exp(-g * (age - 
> Xintercept)))))
>   nls(formula=gomp,data=data,start=start)
> }
> 
> When I run the function, I get the following error:
> 
>  > Gompertz(growth,0,87,list(k=0.5,g=0.5))
> Error in eval(expr, envir, enclos) : Object "Lzero" not found
> 
> After reading through the help files on 'nls', 'formula', 'model.frame', 
> and 'environment', I understand that the formula gets evaluated in the 
> environment in which it is created, and in my case, "Lzero" is not 
> defined in that environment, but I'm still shaky on the environment 
> concept and can't figure out how to pass or include "Lzero" in the 
> environment that nls is evaluating gomp and data in.
> 
> I have tried redefining "gomp" in the function as:
> 
> gomp <- as.formula("length ~ Lzero * exp(k * (1 - exp(-g * (age - 
> Xintercept))))",environment()) 
> # thinking that 'environment()' refers to environment of Gompertz 
> function where Lzero exists
> 
> gomp <- as.formula("length ~ Lzero * exp(k * (1 - exp(-g * (age - 
> Xintercept))))",environment(Gompertz))
> # trying to explicitly force it
> 
> gomp <- as.formula("length ~ Lzero * exp(k * (1 - exp(-g * (age - 
> Xintercept))))",new.env())
> # my guess at what formula(x,...) does
> 
> ...but I get the same error. Since I'm still trying to wrap my head 
> around environments and evaluation in R, the solution to this will be 
> very educational.  Thanks in advance.
> 
> Cheers,
> e.
> 

Hi, Eric,

I think the easiest way to do this is to use substitute:

# return gompertz fit
Gompertz <- function(data, Xintercept, Lzero, start) {
   gomp <- substitute(length ~ Lzero * exp(k * (1 - exp(-g * (age - 
Xintercept)))),
                      list(Xintercept = Xintercept, Lzero = Lzero))
   nls(gomp, data, start)
}

Gompertz(growth, 0, 87, list(k = 0.5, g = 0.5))

HTH,

--sundar




More information about the R-help mailing list