Re: [R] eval and parent.frame [was: Error in Design package: dataset not found for options(datadist)]

From: Charles C. Berry <cberry_at_tajo.ucsd.edu>
Date: Mon, 21 Apr 2008 21:09:40 -0700

On Tue, 22 Apr 2008, Gad Abraham wrote:

> Charles C. Berry wrote:

>> On Sat, 19 Apr 2008, Gad Abraham wrote:
>>
>>> 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 :)
>>
>> Well, the ultimate problem is here
>>
>> <from Design>
>>   XDATADIST <- .Options$datadist
>>     if (length(XDATADIST)) {
>>         if (!exists(XDATADIST))
>>             stop(paste("dataset", XDATADIST, "not found for
>> options(datadist=)"))
>> ...
>>
>> exists()  mandates that there be an object as.name(XDATADIST) in the
>> search() list. And a further eval(as.name(XDATADIST)) also requires this.
>>
>> Another way to do make your function work is to use this in it:
>>
>>     on.exit( detach("design.options") )
>>     attach(list(), name= "design.options" )
>>     d <- data.frame(ch, age)
>>        assign('dd', datadist(d), pos='design.options')
>>
>> Admittedly still a hack, but it keeps your function from messing around
>> with .GlobalEnv, and unless you are willing to rewrite lrm and Design,
>> this is what you are stuck with.
>
>

> I've changed the original example to:
>

> library(Design)
> attach(list(), name="design.options")
> on.exit(detach("design.options"))
> 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)
> assign('dd', datadist(d), pos='design.options')
> options(datadist="dd")
> lrm(ch ~ age, data=d, x=TRUE, y=TRUE)
> }
>

> fit(ch, age)
>
>

> This works when I paste it into the R console, but not when I source()
> the script:
>
>

> > library(Design)
> Loading required package: Hmisc
> ...
> > attach(list(), name="design.options")
> > on.exit(detach("design.options"))
> > 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)
> + assign('dd', datadist(d), pos='design.options')
> + options(datadist="dd")
> + lrm .... [TRUNCATED]
> > fit(ch, age)
> Error in as.environment(pos) :
> no item called "design.options" on the search list
>
> Or is that asking for too much? ;)

Well, I did say to use that bit of code IN your function.

Like this:

age <- rnorm(30, 50, 10)
cholesterol <- rnorm(30, 200, 25)
ch <- cut2(cholesterol, g=5, levels.mean=TRUE)

fit <- function(ch, age){

   on.exit(detach("design.options"))
   attach(list(), name="design.options")    d <- data.frame(ch, age)
   assign('dd', datadist(d), pos='design.options')    options(datadist="dd")
   lrm(ch ~ age, data=d, x=TRUE, y=TRUE) }

print(fit(ch,age))

HTH, Chuck

>

> --
> 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
>

> ______________________________________________
> R-help_at_r-project.org mailing list
> https://stat.ethz.ch/mailman/listinfo/r-help
> PLEASE do read the posting guide http://www.R-project.org/posting-guide.html
> and provide commented, minimal, self-contained, reproducible code.
>
Charles C. Berry                            (858) 534-2098
                                             Dept of Family/Preventive Medicine
E mailto:cberry_at_tajo.ucsd.edu	            UC San Diego
http://famprevmed.ucsd.edu/faculty/cberry/ La Jolla, San Diego 92093-0901

R-help_at_r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-help PLEASE do read the posting guide http://www.R-project.org/posting-guide.html and provide commented, minimal, self-contained, reproducible code. Received on Tue 22 Apr 2008 - 04:14:01 GMT

Archive maintained by Robert King, hosted by the discipline of statistics at the University of Newcastle, Australia.
Archive generated by hypermail 2.2.0, at Tue 22 Apr 2008 - 07:30:30 GMT.

Mailing list information is available at https://stat.ethz.ch/mailman/listinfo/r-help. Please read the posting guide before posting to the list.

list of date sections of archive