Will Beason
Will Beason

Reputation: 3551

How can I create a slot in an S4 class for robust linear models?

I would like to create an S4 class that has slots which can hold robust linear models.

Robust linear models are a type of linear model from the MASS package. They carry all of the information a linear model has and a bit more.

library(MASS)
x <- 1:5
y <- 1:5
mylm <- lm(x~y)
myrlm <- rlm(x~y)

Here is my class:

.MyClass <- setClass("MyClass", list(a="lm", id="numeric"))

Even though .MyClass(a=mylm, id=1) produces the expected object, initializing an object with an rlm fails:

> .MyClass(a=myrlm, id=1)
Error in validObject(.Object) : 
  invalid class “MyClass” object: 1: invalid object for slot "a" in class "MyClass": got class "rlm", should be or extend class "lm"
invalid class “MyClass” object: 2: invalid object for slot "a" in class "MyClass": got class "lm", should be or extend class "lm"

I would have thought that since is(myrlm, "lm") returns TRUE there wouldn't be an issue and the object could fit in the slot. Also, since it is telling me I created an invalid object twice, why is the second one saying that lm is not itself? Is it because lm is a virtual class?

I've tried setting a="list" in the representation (since lm and rlm are both lists), but that produces a similar error. Does the slot need a different class type? I've also tried setting a="rlm", but rlm is not defined class.

Upvotes: 6

Views: 224

Answers (1)

nicola
nicola

Reputation: 24480

The problem seems to be the fact that rlm objects has two S3 classes. I suggest, as a work-around, to define a constructor and change the class of the slots before creating the object. Something along these lines:

   library(MASS)
   x <- 1:5
   y <- 1:5
   mylm <- lm(x~y)
   myrlm <- rlm(x~y)
   .MyClass <- setClass("MyClass", list(a="lm", id="numeric"))
   MyClass<-function(a,id) {
     if (!is(a,"lm")) stop("error")
     class(a)<-"lm"
     new("MyClass",a=a,id=id)
   }
   MyClass(myrlm,1)

Upvotes: 2

Related Questions