On 4/5/06, Prof Brian Ripley <[EMAIL PROTECTED]> wrote: > On Wed, 5 Apr 2006, Henrik Bengtsson wrote: > > > Hi, > > > > forget about the below details. It is not related to the fact that > > the function is returned from a function. Sorry about that. I've > > been troubleshooting soo much I've been shoting over the target. Here > > is a much smaller reproducible example: > > > > x <- 1:10 > > y <- 1:10 + rnorm(length(x)) > > sp <- smooth.spline(x=x, y=y) > > ypred <- predict(sp$fit, x) > > # [1] 2.325181 2.756166 ... > > ypred2 <- predict(sp$fit, c(0,x)) > > # Error in Recall(object, xrange) : couldn't find > > # function "predict.smooth.spline.fit" > > It seems Recall is not searching (via findFun) from the right environment, > but at a quick glance it is not obvious to me why. > You can replace Recall by predict.smooth.spline.fit for now.
More troubleshooting shows that by dispatching directly on 'sp' and not 'sp$fit' works. The reason that I do not want to do this is related to my questions yesterday that I want to keep the memory usage down and 'sp' hold quite some extra data even with keep.data=FALSE. Example show how it works: x <- 1:10 y <- 1:10 + rnorm(length(x)) sp <- smooth.spline(x=x, y=y) The following two calls work: ypred1 <- predict(sp, x) ypred2 <- predict(sp, c(0,x)) They dispatch on predict.smooth.spline(), which in turn calls predict(sp$fit, ...) which dispatch on predict.smooth,spline.fit(); > getAnywhere("predict.smooth.spline") A single object matching 'predict.smooth.spline' was found It was found in the following places registered S3 method for predict from namespace stats namespace:stats with value function (object, x, deriv = 0, ...) { if (missing(x)) { if (deriv == 0) return(object[c("x", "y")]) else x <- object$x } fit <- object$fit if (is.null(fit)) stop("not a valid \"smooth.spline\" object") else predict(fit, x, deriv, ...) } <environment: namespace:stats> Trying to do the same without the first step, that is, to call predict(sp$fit, ...) to dispatch on predict.smooth,spline.fit() directly, then the second will fail due to the Recall(); ypred3 <- predict(sp$fit, x) ypred4 <- predict(sp$fit, c(0,x)) # Error! Note that both predict.smooth.spline() and predict.smooth.spline.fit() are under the "namespace hood", i.e. not exported. So, no apparent difference there. To avoid the overhead of some of the elements of 'sp' I create a minimal 'smooth.spline' object like this: fit <- structure(list(fit=sp$fit), class=class(sp)) ypred5 <- predict(fit, x) ypred6 <- predict(fit, c(0,x)) # Error! and it all works. I don't really like to fake objects like this, although allowed in S3. But for now it's ok. However, it would be interesting to know/understands what is going on. /Henrik [snip] > > > > /Henrik > > > > > > On 4/5/06, Henrik Bengtsson <[EMAIL PROTECTED]> wrote: > >> Hi, > >> > >> yesterday I got very useful feedback on what is the best way to return > >> a function from a function. > >> > >> Now, I run into a problem calling a returned function that down the > >> stream uses Recall(). Below is a self-contained example. I took away > >> yesterday's code for returning a minimal environment for the function, > >> because that is not related to this problem. > >> > >> getPredictor <- function(x, y) { > >> sp <- smooth.spline(x=x, y=y, keep.data=FALSE) > >> function(x, ...) predict(sp$fit, x, ...)$y > >> } > >> > >> # Simulate data > >> x <- 1:10 > >> y <- 1:10 + rnorm(length(x)) > >> > >> # Estimate predictor function > >> fcn <- getPredictor(x,y) > >> > >> # No extrapolation => no Recall() > >> ypred <- fcn(x) > >> print(ypred) > >> # Gives: # [1] 2.325181 2.756166 ... > >> > >> # With extrapolation => Recall() > >> xextrap <- c(0,x) > >> ypred <- fcn(xextrap) > >> # Gives: # Error in Recall(object, xrange) : couldn't find > >> # function "predict.smooth.spline.fit" > >> > >> To see what's the function looks like, do > >> > >> pfcn <- getAnywhere("predict.smooth.spline.fit")$obj[[2]] > >> page(pfcn) > >> > >> A workaround is to set the predict.smooth.spline.fit() in .GlobalEnv, i.e. > >> > >> predict.smooth.spline.fit <- pfcn > >> > >> Does Recall() have a problem because predict.smooth.spline.fit() is > >> not exported, or what is going on? Are there alternatives to the > >> above workaround? I can see how such a workaround can become very > >> complicated with complex functions where it is hard to predict what > >> functions are called when. > >> > >> /Henrik > >> > >> PS, may I suggest to modify page() so that > >> 'page(getAnywhere("predict.smooth.spline.fit"))' works? DS. > >> > > > > > > -- > > Henrik Bengtsson > > Mobile: +46 708 909208 (+2h UTC) > > > > ______________________________________________ > > R-devel@r-project.org mailing list > > https://stat.ethz.ch/mailman/listinfo/r-devel > > > > > > -- > Brian D. Ripley, [EMAIL PROTECTED] > Professor of Applied Statistics, http://www.stats.ox.ac.uk/~ripley/ > University of Oxford, Tel: +44 1865 272861 (self) > 1 South Parks Road, +44 1865 272866 (PA) > Oxford OX1 3TG, UK Fax: +44 1865 272595 > > -- Henrik Bengtsson Mobile: +46 708 909208 (+2h UTC) ______________________________________________ R-devel@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-devel