[Rd] factor S4 class is NA when as.character method exists

William Dunlap wdunlap at tibco.com
Tue Jan 24 18:17:34 CET 2012


Here is code that does make factor() work on a new
class like yours.  It uses Sv3 methods.
  > setClass("foo", contains="numeric")
  [1] "foo"
  > as.character.foo <- function(x) paste("x=",x at .Data,sep="")
  > unique.foo <- function(x, ...) structure(NextMethod("unique"), class=class(x))
  > someFoo <- new("foo", c(11, 13, 11, 13, 12))
  > str(factor(someFoo))
   Factor w/ 3 levels "x=11","x=12",..: 1 3 1 3 2

It would be nice to have a list of methods that one
needs to define for a new class in order to make it
do the "basic" things you expect.

Bill Dunlap
Spotfire, TIBCO Software
wdunlap tibco.com 

> -----Original Message-----
> From: r-devel-bounces at r-project.org [mailto:r-devel-bounces at r-project.org] On Behalf Of Dan Murphy
> Sent: Monday, January 23, 2012 10:31 PM
> To: peter dalgaard
> Cc: r-devel at r-project.org
> Subject: Re: [Rd] factor S4 class is NA when as.character method exists
> 
> Thank you for your reply, Peter. But that didn't work either. Continuing
> the example:
> 
> setGeneric("unique")
> setMethod("unique", "foo",  function(x,  incomparables = FALSE, ...){
>     y <- callNextMethod(x = getDataPart(x),  incomparables = incomparables,
> ...)
>     new("foo", y)
>     })
> 
> > unique(bar)
> An object of class "foo"
> [1] 12
> > factor(bar)
> [1] <NA>
> Levels: 12
> 
> Indeed I had tried stepping through the 'factor' call, but perhaps in an
> unsophisticated manner -- I had copied the body of 'factor' to a local
> version of the function:
> 
> myfactor <- function (x = character(), levels, labels = levels, exclude =
> NA,
>     ordered = is.ordered(x))
> {
>     if (is.null(x)) ...
> etc.
> 
> And 'myfactor' worked as desired:
> 
> > myfactor(bar)
> [1] x= 12
> Levels: x= 12
> 
> I hypothesized that there might be a deeper interaction of an S4
> 'as.character' method with base::factor, but, having exhausted my woeful
> lack of expertise, I decided to write my original email.
> 
> Thanks for your consideration.
> 
> Dan
> 
> On Mon, Jan 23, 2012 at 8:25 AM, peter dalgaard <pdalgd at gmail.com> wrote:
> 
> >
> > On Jan 23, 2012, at 16:07 , Dan Murphy wrote:
> >
> > > Hello,
> > >
> > > 'factor' returns <NA> for my S4 object when the class is given an
> > > "as.character" method. Here is a minimal example:
> > >
> > >> setClass("foo", contains="numeric")
> > >> bar <- new("foo", 12)
> > >> factor(bar)
> > > [1] 12
> > > Levels: 12
> > >> setMethod("as.character", "foo", function(x) paste("x=", x at .Data))
> > > [1] "as.character"
> > >> as.character(bar)
> > > [1] "x= 12"
> > >> factor(bar)
> > > [1] <NA>
> > > Levels: 12
> > >
> > > I would like to 'aggregate' by my S4 objects, but 'factor' seems to be
> > > getting in the way. Is there an 'as.character' implementation that works
> > > better for S4 classes? I searched help.search("factor S4 class") and
> > > help.search("factor S4 as.character") without success.
> >
> > Single-stepping the factor call would have shown you that the real problem
> > is that you don't have a unique() method for your class:
> >
> > > unique(bar)
> > [1] 12
> >
> > i.e., you are getting the default numeric method, which returns a numeric
> > vector, so the levels become as.character(unique(bar)) which is c("12") and
> > doesn't match any of the values of as.character(bar).
> >
> > So, either provide a unique() method, or use factor(as.character(bar)).
> >
> > >
> > > Thank you.
> > >
> > > Dan Murphy
> > >
> > >       [[alternative HTML version deleted]]
> > >
> > > ______________________________________________
> > > R-devel at r-project.org mailing list
> > > https://stat.ethz.ch/mailman/listinfo/r-devel
> >
> > --
> > Peter Dalgaard, Professor
> > Center for Statistics, Copenhagen Business School
> > Solbjerg Plads 3, 2000 Frederiksberg, Denmark
> > Phone: (+45)38153501
> > Email: pd.mes at cbs.dk  Priv: PDalgd at gmail.com
> >
> >
> 
> 	[[alternative HTML version deleted]]
> 
> ______________________________________________
> R-devel at r-project.org mailing list
> https://stat.ethz.ch/mailman/listinfo/r-devel



More information about the R-devel mailing list