[R] nls and R scoping rules
Prof Brian Ripley
ripley at stats.ox.ac.uk
Thu Jun 10 10:55:11 CEST 2004
On Thu, 10 Jun 2004, joerg van den hoff wrote:
> I apologize for posting this in essence the second time (no light at the
> end of the tunnel yet..):
>
> is there a way to enforce that "nls" takes both, the data *and* the
> model definition from the parent environment? the following fragment
> shows the problem.
>
> #======== cut here==========
> wrapper <- function (choose=0)
> {
> x <- seq(0,2*pi,len=100)
> y <- sin(1.5*x);
> y <- rnorm(y,y,.1*max(y))
>
> if (choose==0) {
> rm(fifu,pos=1)
> fifu <- function(w,x) {sin(w*x)}
> }
> else
> assign('fifu',function(w,x) {sin(w*x)},.GlobalEnv)
>
> res <- nls(y ~ fifu(w,x),start=list(w=1))
> res
> }
> #======== cut here==========
>
> if called as "wrapper(1)" this runs fine because the fitting function
> "fifu" is assigned in the GlobalEnv.
> if called as "wrapper(0)", "fifu" is defined only locally and "nls"
> (actually, "nlsModel", I think) does not know what I'm talking about.
>
> I understand, the problem is that the scoping rules are such that "nls"
> does not resolve 'fifu' in the parent environment, but rather in the
> GlobalEnv. (this is different for the data, which *are* taken from the
> parent environment of the nls-call).
I assume by `data' you mean not the `data' argument to nls but the
variables referred to in your formula.
> I tried some variants of using "eval" but without starting to modify
> "nls" itself there seems no way (up to now, anyway).
>
> The solution to "assign" 'fifu' directly into the GlobalEnv does work,
> of course, but leads to the undesirable effect of accumulating objects
> in the workspace which are not needed there (and might overwrite
> existing ones).
S has frame 1 for this purpose. The nearest equivalent I know in R is to
attach an environment in position 2 and assign objects like 'fifu' there,
which avoids your `undesirable effect'.
> in response to my first post, I got the hint that for "lm" the situation
> is different: it handles the above situation as desired (i.e. accepts
> local model definition). in so far one might even argue that this
> behaviour of "lm" and "nls" leads to an inconsistent behaviour of R in
> quite similar situations (e.g. replacing at some point a linar model by
> a nonlinear model in some large project is not achieved by simply
> replacing "lm" by "nls" somewhere deep down in the source code).
I think that is simply wrong. It is a _function_ in your non-linear model
definition that is not being found, not the variables (which you call
`data' above). You do currently need to ensure that the functions in your
formulae are in scope when called from nlsModel.
Around R 1.2.x the notion was introduced that variables should be looked
for in the environment of a formula. Functions using model.frame got
converted to do that, but nls did not. I guess that the best way forward
is to ensure that nls (and nlsModel) does search the environment of the
formula for functions.
--
Brian D. Ripley, ripley at stats.ox.ac.uk
Professor of Applied Statistics, http://www.stats.ox.ac.uk/~ripley/
University of Oxford, Tel: +44 1865 272861 (self)
1 South Parks Road, +44 1865 272866 (PA)
Oxford OX1 3TG, UK Fax: +44 1865 272595
More information about the R-help
mailing list