FAQ
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úLSE,
ratetable=survexp.us, scale=1, npoints, se.fit,
modelúLSE, xúLSE, yúLSE) {
call <- match.call()
m <- match.call(expand.dotsúLSE)

# 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

Search Discussions

  • Gabor Grothendieck at Nov 11, 2010 at 9:07 pm

    On Thu, Nov 11, 2010 at 3: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úLSE,
    ? ? ? ?ratetable=survexp.us, scale=1, npoints, se.fit,
    ? ? ? ?modelúLSE, xúLSE, yúLSE) {
    ? ?call <- match.call()
    ? ?m <- match.call(expand.dotsúLSE)

    ? ?# 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='+')
    At the above statement you have lost the environment of your formula.
    ? ?m$formula <- tform
    Replace this with:

    m$formula <- as.formula(tform, environment(formula))



    --
    Statistics & Software Consulting
    GKX Group, GKX Associates Inc.
    tel: 1-877-GKX-GROUP
    email: ggrothendieck at gmail.com
  • Terry Therneau at Nov 11, 2010 at 10:27 pm
    Gabor wrote:
    At the above statement you have lost the environment of your formula.
    m$formula <- tform
    Replace this with:

    m$formula <- as.formula(tform, environment(formula))

    ----------------------
    No, I have not "lost" an environment. I manufactured a formula which
    lacked something needed, but without the necessary hint that I needed
    it. But that is semantics: A closer reread of help(model.frame) shows
    that the documentation is there, I had missed it.

    I'm still puzzled by recover though.

    Terry T.
  • Gabor Grothendieck at Nov 11, 2010 at 10:31 pm

    On Thu, Nov 11, 2010 at 5:27 PM, Terry Therneau wrote:
    Gabor wrote:
    ?At the above statement you have lost the environment of your formula.
    ? ?m$formula <- tform
    Replace this with:

    m$formula <- as.formula(tform, environment(formula))

    ----------------------
    ?No, I have not "lost" an environment. ?I manufactured a formula which
    You manufactured a "character" string, not a "formula", and character
    strings don't have environments.
    lacked something needed, but without the necessary hint that I needed
    it. But that is semantics: ?A closer reread of help(model.frame) shows
    that the documentation is there, I had missed it.

    ?I'm still puzzled by recover though.

    Terry T.


    --
    Statistics & Software Consulting
    GKX Group, GKX Associates Inc.
    tel: 1-877-GKX-GROUP
    email: ggrothendieck at gmail.com
  • Peter Dalgaard at Nov 11, 2010 at 11:25 pm

    On 11/11/2010 11:27 PM, Terry Therneau wrote:

    I'm still puzzled by recover though.
    It looks like a buglet. You get to the right frame (try ls()) but the
    "called from" message is off by four frames.

    E.g.

    Selection: 1
    Called from: model.frame(formula = "zed ~ 1+age+sex+year", data = mydata)
    Browse[1]> ls()
    [1] "mydata" "zed"
    Browse[1]> tfun
    function(mydata) {
    zed <- 100 + (1:nrow(mydata)) * 20
    survexp.test(zed ~ 1, data=mydata)
    }

    --
    Peter Dalgaard
    Center for Statistics, Copenhagen Business School
    Phone: (+45)38153501
    Email: pd.mes at cbs.dk Priv: PDalgd at gmail.com
  • Kevin R. Coombes at Nov 11, 2010 at 10:31 pm
    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úLSE,
    ratetable=survexp.us, scale=1, npoints, se.fit,
    modelúLSE, xúLSE, yúLSE) {
    call<- match.call()
    m<- match.call(expand.dotsúLSE)

    # 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 at r-project.org mailing list
    https://stat.ethz.ch/mailman/listinfo/r-devel
  • Terry Therneau at Nov 11, 2010 at 11:08 pm
    Kevin,
    The answer came from Gabor -- the model.frame function has a
    non-standard evaluation, in that it uses the enviromnent attached to the
    formula as the "enclosure" for looking up variable names.
    This is clearly documented and I somehow missed it when reading the
    page. So "reading deficit" is the true root of my query. I scratched
    my head for a couple of hours before sending for help.

    Also a typo in my stripped down example -- I forgot the as.formula()
    wrapper which is in the actual survexp function. This added a red
    herring to the discussion.

    Terry T.

Related Discussions

Discussion Navigation
viewthread | post
Discussion Overview
groupr-devel @
categoriesr
postedNov 11, '10 at 8:08p
activeNov 11, '10 at 11:25p
posts7
users4
websiter-project.org
irc#r

People

Translate

site design / logo © 2022 Grokbase