[Rd] predict.smooth.spline.fit and Recall() (Was: Re: Return function from function and Recall())
Henrik Bengtsson
hb at maths.lth.se
Wed Apr 5 13:58:15 CEST 2006
On 4/5/06, Prof Brian Ripley <ripley at stats.ox.ac.uk> 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 <hb at maths.lth.se> 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 at r-project.org mailing list
> > https://stat.ethz.ch/mailman/listinfo/r-devel
> >
> >
>
> --
> Brian D. Ripley, ripley at stats.ox.ac.uk
> 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)
More information about the R-devel
mailing list