Hi Terry,

This may not really be a complete answer, but there seems to be a difference in eval'ing an expression compared to eval'ing a call (even though both are documented in the help page for eval as working just fine).

If you insert the line
    print(eval(expression(zed), parent.frame()))
into your survexp.test function just above the existing call to "eval", this line works just fine. So it's clear that an _expression_ containing "zed" can be evaluated, but evaluating the _call_ via the model.frame function fails.

I suspect that the actual evaluation problem lies in the call to
    eval(predvars, data, env)
made inside model.frame.default. The value of "env" when this function is called is defined in an earlier line by
    env <- environment(formula)
Since the formula does not have an environment defined when it is passed in, one gets provided within the model.frame.default function. I edited my version of model.frame.default to
    print(ls(env))
just before the call to
    eval(predvars, data, env)
and confirmed that "zed" is not part of that environment.

Now the manual page for formula says that "Formulas created with ~ use the environment in which they were created. Formulas created with 'as.formula' use the env argument for their environment." Since you are passing a character string through to model.frame, and it calls "as.formula" without an environment, the formula eventually gets evaluated in the context of the model.frame.default function without knowing about the environment you gave it.

I think you can fix this by explicitly creating your own formula+environment before calling miodel frame. Specifically, try changing the line
    m$formula <- tform
to
    m$formula <- as.formula(tform, env=parent.frame())
and see if that helps.  On my machine, it at least allows
    tfun(tdata)
to run without throwing an error.

Best,
    Kevni


On 11/11/2010 2:08 PM, Terry Therneau wrote:
The survexp function can fail when called from another function.  The "why" of
this has me baffled, however.

Here is a simple test case, using a very stripped down version of survexp:

survexp.test<- function(formula, data,
         weights, subset, na.action, rmap,
         times,  cohort=TRUE,  conditional=FALSE,
         ratetable=survexp.us, scale=1, npoints, se.fit,
         model=FALSE, x=FALSE, y=FALSE) {
     call<- match.call()
     m<- match.call(expand.dots=FALSE)

     # keep the first element (the call), and the following selected arguments
     m<- m[c(1, match(c('formula', 'data', 'weights', 'subset', 'na.action'),
                       names(m), nomatch=0))]
     m[[1]]<- as.name("model.frame")

     # Add in the ratetable variables
     varlist<- attr(ratetable, 'dimid')
     tform<- paste(deparse(formula), paste(varlist, collapse='+'), sep='+')
     m$formula<- tform

     print(m)
     print(ls(parent.frame()))
     mf<- eval(m, parent.frame())

     names(mf)
     }

Here is the test data

tdata<- data.frame(age= c(12, 24, 36)*365.25, sex=c(1,2,1),
                     year=as.Date('1953/03/10', '1960/02/23', '1978/09.22'))
tfun<- function(mydata) {
      zed<- 100 + (1:nrow(mydata)) * 20
      survexp.test(zed ~ 1, data=mydata)
      }

And the result of the exercise.

% R --vanilla
R version 2.11.0 (2010-04-22)

library(survival)    # to pick up the survexp.us data
tfun(tdata)
model.frame(formula = "zed ~ 1+age+sex+year", data = mydata)
[1] "mydata" "zed"
Error in eval(expr, envir, enclos) : object 'zed' not found

-----
  Eval is being called with the expression shown and an environment that
contains the relevant variables in that expression: zed and mydata.  Yet it
fails to find the variable zed.

  I don't see anything relevant in the manual pages for either eval or
model.frame.  I suspect that there is an invisible, undocumented, magic
argument somewhere.


My second problem is a puzzler:

options(error=recover)
tfun(tdata)
model.frame(formula = "zed ~ 1+age+sex+year", data = mydata)
[1] "mydata" "zed"
Error in eval(expr, envir, enclos) : object 'zed' not found

Enter a frame number, or 0 to exit

1: tfun(tdata)
2: survexp.test(zed ~ 1, data = mydata)
3: eval(m, parent.frame())
4: eval(expr, envir, enclos)
5: model.frame(formula = "zed ~ 1+age+sex+year", data = mydata)
6: model.frame.default(formula = "zed ~ 1+age+sex+year", data = mydata)
7: eval(predvars, data, env)
8: eval(expr, envir, enclos)

Selection: 2
Called from: model.frame.default(formula = "zed ~ 1+age+sex+year", data = 
mydata)


  Why does selecting "2" result in going to frame "6"?

Terry Therneau

______________________________________________
R-devel@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel

______________________________________________
R-devel@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel

Reply via email to