Charles C. Berry wrote: > 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. >
That nuance was lost on me. Thanks! -- Gad Abraham Dept. CSSE and NICTA The University of Melbourne Parkville 3010, Victoria, Australia email: [EMAIL PROTECTED] web: http://www.csse.unimelb.edu.au/~gabraham ______________________________________________ R-help@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.