Как я могу создать слот в классе S4 для надежных линейных моделей?

Я хотел бы создать класс S4, в котором есть слоты, в которых могут храниться надежные линейные модели.

Надежные линейные модели — это тип линейной модели из пакета MASS. Они несут всю информацию, которую имеет линейная модель, и немного больше.

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(a=mylm, id=1) создает ожидаемый объект, инициализация объекта с помощью rlm завершается ошибкой:

> .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"

Я бы подумал, что, поскольку is(myrlm, "lm") возвращает TRUE, проблем не будет, и объект сможет поместиться в слот. Кроме того, поскольку он говорит мне, что я дважды создал недопустимый объект, почему второй говорит, что lm не является самим собой? Это потому, что lm — виртуальный класс?

Я попытался установить a="list" в представлении (поскольку lm и rlm оба являются списками), но это приводит к аналогичной ошибке. Нужен ли слоту другой тип класса? Я также пытался установить a="rlm", но rlm не является определенным классом.


person Will Beason    schedule 30.09.2014    source источник
comment
отличный вопрос. Я подозреваю, что вы скатываетесь в ад несовместимости S3/S4, но я надеюсь (ради вас), что это не так. Вы можете (???) попробовать создать класс S4, который охватывает/обертывает класс S3 rlm...?   -  person Ben Bolker    schedule 01.10.2014


Ответы (1)


Проблема, по-видимому, заключается в том, что объекты rlm имеют два класса S3. Я предлагаю в качестве обходного пути определить конструктор и изменить класс слотов перед созданием объекта. Что-то в этом роде:

   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)
person nicola    schedule 30.09.2014
comment
Ницца! Я думаю, поскольку lm является виртуальным классом, на самом деле нет никакой проверки объекта. Похоже, это работает для любого объекта, похожего на список, и виртуального класса. - person Will Beason; 01.10.2014