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