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