为什么有时我不能将类定义设置为s4类中的槽?

Act*_*uzo 6 r class s4

r=ks.test(x=rnorm(100), "dnorm")
class(r)
[1] "htest"


## Doesnt work, "htest" is class in stats
setClass("Jergon", representation(fit="htest"))
[1] "Jergon"
Warning message:
undefined slot classes in definition of "Jergon": fit(class "htest")


## works "lm" 
setClass("Jergon", representation(am="lm"))
[1] "Jergon"
Run Code Online (Sandbox Code Playgroud)

dig*_*All 8

结果ks.test是(来自文档):

类"htest"的列表

因此,实际上"htest"不是定义到包中的正式类,而只是将返回的列表的class属性ks.test设置为"htest".

举个例子,下面的代码也不起作用(因为myclass它不是一个正式的类):

obj = list(foo=123)
class(obj) <- "myclass"

class(obj)
[1] "myclass"

setClass("Jergon", representation(foo="myclass"))
[1] "Jergon"
Warning message:
undefined slot classes in definition of "Jergon": foo(class "myclass") 
Run Code Online (Sandbox Code Playgroud)

要检查一个类是否正式定义(并且可以用作表示),您可以使用getClassDef,即:

> getClassDef('htest')
NULL

> getClassDef('lm')
Virtual Class "lm" [package "methods"]

Slots:

Name:   .S3Class
Class: character

Extends: "oldClass"

Known Subclasses: 
Class "mlm", directly
Class "aov", directly
Class "glm", directly
Class "maov", by class "mlm", distance 2
Class "glm.null", by class "glm", distance 2
Run Code Online (Sandbox Code Playgroud)

编辑:

正如@Martin Morgan正确指出的那样,您可以使用正式注册旧式S3类setOldClass.实际上文档说:

将旧式(又称"S3")类注册为正式定义的类.Classes参数是用作类属性的字符向量; 特别是,如果有多个字符串,则模仿旧式类继承.通过setOldClass注册允许S3类出现在方法签名中,作为S4类中的槽,或作为S4类的超类.

因此,此代码工作正常:

> setOldClass("htest")
> setClass("Jergon", representation(fit="htest"))
[1] "Jergon"
Run Code Online (Sandbox Code Playgroud)

  • 很好的答案; `setOldClass("htest")`告诉正式(S4)类系统你想要将具有类属性`htest`(S3类)的对象视为S4类. (3认同)