[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