From: Henrik Bengtsson <hb_at_maths.lth.se>

Date: Wed 05 Apr 2006 - 11:58:15 GMT

}

fit <- object$fit

if (is.null(fit))

Date: Wed 05 Apr 2006 - 11:58:15 GMT

On 4/5/06, Prof Brian Ripley <ripley@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@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@r-project.org mailing list
**> > https://stat.ethz.ch/mailman/listinfo/r-devel
**> >
**> >
**>
**> --
**> Brian D. Ripley, ripley@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) ______________________________________________ R-devel@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-develReceived on Wed Apr 05 22:22:21 2006

*
This archive was generated by hypermail 2.1.8
: Wed 05 Apr 2006 - 14:17:00 GMT
*