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. HTH, Chuck > > -- > 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 > > Charles C. Berry (858) 534-2098 Dept of Family/Preventive Medicine E mailto:[EMAIL PROTECTED] UC San Diego http://famprevmed.ucsd.edu/faculty/cberry/ La Jolla, San Diego 92093-0901 ______________________________________________ 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.