From jerome at hivnet.ubc.ca  Thu Aug  7 12:16:48 2003
From: jerome at hivnet.ubc.ca (Jerome Asselin)
Date: Thu Aug  7 20:17:06 2003
Subject: [Rd] model.frame() call from inside a function (PR#3671)
In-Reply-To: <x2znilx4uz.fsf@biostat.ku.dk>
References: <200308062241.h76MfoJH002132@pubhealth.ku.dk>
	<x2znilx4uz.fsf@biostat.ku.dk>
Message-ID: <200308071823.LAA00390@hivnet.ubc.ca>


Thanks for your reply and discussion on the issue. See below for another 
suggestion of a fix.

I have spent some time trying to find a fix which would still work as 
documented:
>      Variables in the formula, `subset' and in `...' are looked for
>      first in `data' and then in the environment of `formula': see the
>      help for `formula()' for further details.

The problem is that the expression environment(formula) in 
model.frame.default() gives the value:
(1) <environment: R_GlobalEnv> for the call 
model.frame(formula[-3],data=data,subset=subset) ;
(2) <environment: 0x883d288> (or something alike) for the call
model.frame(~y,data=data,subset=subset) .

In case (1), eval(subset, data, env) in model.frame.default() gives the 
subset() function which leads to an error.
In the case (2), it gives the correct value for subset (i.e., NULL in the 
example of my original message).

I wonder why the environment is not the same for both cases. Don't you? 
Perhaps this is where the real problem is, but my current understanding of 
environment() is too limited to make such a claim.

I suggest here another fix which I hope respects the documentation. In 
model.frame.default(), add the line
    formula <- formula(deparse(formula))
just before the line
    env <- environment(formula)
This change will affect the value of environment(formula).

If you make the correction and run the code below, then it should work 
successfully. The question is whether this change still respects the 
documentation. Personally, I think this is safe, because the expression 
eval(subset, data, env) is still evaluated in the environment of 
`formula', despite the fact that this environment has changed.

Sincerely,
Jerome Asselin

foo <- function(formula,data,subset=NULL)
{
  cat("\n*****Does formula[-3] == ~y ?**** TRUE *****\n")
  print(formula[-3] == ~y)

  cat("\n*****Result of model.frame() using formula[-3]**** FAIL *****\n")
  print(try(model.frame(formula[-3],data=data,subset=subset)))

  cat("\n*****Result of model.frame() using ~y**** WORKS *****\n")
  print(try(model.frame(~y,data=data,subset=subset)))
}
dat <- data.frame(y=c(5,25))
foo(y~1,dat)
foo(y~1,dat,subset=1)

####Results after making the correction###

> foo(y~1,dat)

*****Does formula[-3] == ~y ?**** TRUE *****
[1] TRUE

*****Result of model.frame() using formula[-3]**** FAIL *****
   y
1  5
2 25

*****Result of model.frame() using ~y**** WORKS *****
   y
1  5
2 25
> foo(y~1,dat,subset=1)

*****Does formula[-3] == ~y ?**** TRUE *****
[1] TRUE

*****Result of model.frame() using formula[-3]**** FAIL *****
  y
1 5

*****Result of model.frame() using ~y**** WORKS *****
  y
1 5


[Rd] model.frame() call from inside a function (PR#3671)
Jerome Asselin