[R] eval and parent.frame [was: Error in Design package: dataset not found for options(datadist)]
Gad Abraham
gabraham at csse.unimelb.edu.au
Sat Apr 19 03:30:46 CEST 2008
Charles C. Berry wrote:
> On Fri, 18 Apr 2008, Gad Abraham wrote:
>
>> Frank E Harrell Jr wrote:
>>> Gad Abraham wrote:
>>>> Hi,
>>>>
>>>> Design isn't strictly an R base package, but maybe someone can explain
>>>> the following.
>>>>
>>>> When lrm is called within a function, it can't find the dataset dd:
>>>>
>>>> > library(Design)
>>>> > age <- rnorm(30, 50, 10)
>>>> > cholesterol <- rnorm(30, 200, 25)
>>>> > ch <- cut2(cholesterol, g=5, levels.mean=TRUE)
>>>> > fit <- function(ch, age)
>>>> + {
>>>> + d <- data.frame(ch, age)
>>>> + dd <- datadist(d)
>>>> + options(datadist="dd")
>>>> + lrm(ch ~ age, data=d, x=TRUE, y=TRUE)
>>>> + }
>>>> > fit(ch, age)
>>>> Error in Design(eval(m, sys.parent())) :
>>>> dataset dd not found for options(datadist=)
>>>>
>>>> It works outside a function:
>>>> > d <- data.frame(ch, age)
>>>> > dd <- datadist(d)
>>>> > options(datadist="dd")
>>>> > l <- lrm(ch ~ age, data=d, x=TRUE, y=TRUE)
>>>>
>>>>
>>>> Thanks,
>>>> Gad
>>>
>>> My guess is that you'll need to put dd in the global environment, not in
>>> fit's environment. At any rate it is inefficient to call datadist every
>>> time. Why not call it once for the whole data frame containing all the
>>> predictors, at the top of the program?
>>
>> This is just sample code, in practice the datadist will be different for
>> each invocation of the function.
>>
>> I think it boils down to this behaviour, which I don't understand ---
>> although ls can see x in the parent of f2, eval cannot:
>
>
> That is because (from ?eval):
>
> "Objects to be evaluated can be of types call or expression or name
> (when the name is looked up in the current scope and its binding is
> evaluated)..."
>
> And 'x' is of type name (aka 'symbol').
>
> So eval never gets around to looking in 'p', because it never succeeded
> in looking up 'x' and evaluating its binding in the current scope.
>
> What you probably want is
>
> b <- evalq( x, envir=p)
>
Thanks, that solves the problem with this sample code, but not with the
Design::lrm function, because there are several more layers of
evaluation there.
I can get around that with the ugly hack of setting a global NULL
datadist and assigning to it with "<<-" within the fit function every
time, so it's always visible to Design. But it's still an ugly hack :)
--
Gad Abraham
Dept. CSSE and NICTA
The University of Melbourne
Parkville 3010, Victoria, Australia
email: gabraham at csse.unimelb.edu.au
web: http://www.csse.unimelb.edu.au/~gabraham
More information about the R-help
mailing list