[Rd] Methods package is now attached by default

Torsten Hothorn Torsten.Hothorn@rzmail.uni-erlangen.de
Mon Jan 20 10:34:02 2003


On Sun, 19 Jan 2003, Kurt Hornik wrote:

> >>>>> Prof Brian D Ripley writes:
>
> > On Fri, 17 Jan 2003, John Chambers wrote:
> >> There are two main known differences from having methods attached:
> >>
> >> - the definition of class() changes, in particular no object ever has a
> >> NULL class.  If you have code that depends on test such as
> >> `if(is.null(class(x)))...', there may be problems.
> >>
> >> Usually code with those sort of tests is doing a workaround of the fact
> >> that not all objects had a class before.  The best solution is usually
> >> to ask what the code really wants to do.  If you do have to retain
> >> exactly the old behavior, one solution is to copy the version of class
> >> and class<- from the base package and use those (as baseClass and
> >> baseClass<-, e.g.) instead of class and class<-).
>
> > Here is one example, which makes the MASS scripts fail.
>
> >> library(MASS)
> >> corresp
> > function (x, ...)
> > {
> >     if (is.null(class(x)))
> >         class(x) <- data.class(x)
> >     UseMethod("corresp", x, ...)
> > }
>
> > That used to work with matrices, and dispatch to corresp.matrix.  Now
> > a matrix has reported class "matrix" but dispatch occurs to
> > corresp.default.  The temporary fix is to remove the is.null
> > condition.
>
> > That's quite a common construction, and I think I should expect
> > UseMethod to dispatch on the class class() reports.  So it looks to me
> > as if UseMethod needs to be altered to do so.
>

same happens e.g. with class "numeric":

ipredbagg <- function(y, ...) UseMethod("ipredbagg")

does NOT dispatch to ipredbagg.numeric if y IS of class "numeric". With
the "old" class(), this one worked:

ipredbagg.default <- function(y, ...) {
  # "numeric" is not an S3 class: check for regression problems and
  # the method dispatch should work for class(y) == "numeric"
  if (is.numeric(y)) {
    class(y) <- "numeric"
    return(ipredbagg(y, ...))
  } else {
    stop(paste("Do not know how to handle objects of class", class(y)))
  }
}

but now I need to call

return(ipredbagg.numeric(y, ...))

I think Brian is right with altering UseMethod() in a way taking care of
what class() tells us.

> > ...
>
> The daily check process on all CRAN packages shows that the packages
>
> 	StatDataML geoR ipred xtable
>
> now fail running their examples with methods loaded by default.  The
> three latter can be traced immediately to variations on the above; the
> first fails in
>
>     if (is.factor(x)) {
>       attr(xtmp, "levels") <- NULL
>       class(xtmp) <- class(xtmp)[!class(xtmp) %in% c("ordered","factor")]
>     }
>
> with the error message
>
> Error in "class<-"(*tmp*,
>                    value = class(xtmp)[!class(xtmp) %in% c("ordered",  :
>         Invalid replacement object to be a class string
>
> I think I can tell David how to fix this, but wasn't quite sure about
> the wording in the error message ...
>
> I assume I should wait before contacting the authors of the other 3
> packages for changing their code---or do we already have an official
> recommendation?

I can fix the code for ipred. The only problem is making it work for both
R-1.6.2  AND  R-devel :-)

Torsten

>
> -k
>
> ______________________________________________
> R-devel@stat.math.ethz.ch mailing list
> http://www.stat.math.ethz.ch/mailman/listinfo/r-devel
>
>