如果我有S4课,例如:
setClass("MyClass",
representation(
data="data.frame",
name="character"))
并将其实例化(例如obj
),
obj <- new('MyClass', data=data.frame(1:3), name='An S4 class')
我将具有以下表示形式:
An object of class "MyClass"
Slot "data":
X1.3
1 1
2 2
3 3
Slot "name":
[1] "An S4 class"
到现在为止还挺好。
但是,如果我尝试使用以下方法来更改“类”:
class(obj) <- "animal"
我现在得到
An object of class "animal"
<S4 Type Object>
attr(,"data")
X1.3
1 1
2 2
3 3
attr(,"name")
[1] "An S4 class"
如果我尝试检查它是否仍然是S4类,它将返回true:
>isS4(obj)
[1] TRUE
到底是怎么回事?为什么“插槽”更改为属性?这真的仍然是S4班吗?
更新:
感谢您的全面解答。只是为了澄清一下,我并不希望这能在任何实际情况下起作用或使用。我只是想更好地了解这种行为背后的机制。另外,很难选择一个“最佳”答案(它们都是非常好的),但是按照SO的精神,我必须选择一个。
S4将插槽实现为属性。这通常对用户隐藏,但很容易看到
> attributes(setClass("MyClass", representation(x="integer"))())
$x
integer(0)
$class
[1] "MyClass"
attr(,"package")
[1] ".GlobalEnv"
更详细一点,我们有
> .Internal(inspect(setClass("MyClass", representation(x="integer"))()))
@1fe4dfd8 25 S4SXP g0c0 [OBJ,NAM(2),S4,gp=0x10,ATT]
ATTRIB:
@1fe4dfa0 02 LISTSXP g0c0 []
TAG: @23c8978 01 SYMSXP g0c0 [MARK,NAM(2)] "x"
@1fe4df68 13 INTSXP g0c0 [] (len=0, tl=0)
TAG: @2363208 01 SYMSXP g0c0 [MARK,NAM(2),LCK,gp=0x4000] "class" (has value)
@1fd9f1b8 16 STRSXP g0c1 [NAM(2),ATT] (len=1, tl=0)
@2e09e138 09 CHARSXP g0c1 [gp=0x61] [ASCII] [cached] "MyClass"
ATTRIB:
@1fd9fb20 02 LISTSXP g0c0 []
TAG: @236cc00 01 SYMSXP g0c0 [MARK,NAM(2)] "package"
@1fd9f278 16 STRSXP g0c1 [NAM(2)] (len=1, tl=0)
@23cc938 09 CHARSXP g0c2 [MARK,gp=0x61] [ASCII] [cached] ".GlobalEnv"
这表明用于表示所有R对象的基础S表达式是S4SXP,带有附加的属性列表。
class<-
正如@hadley所指出的那样,通过使用S3-ism,您创建了一个混合怪物。class<-
仅更新class属性,而不更改基础S4SXP。当您打印对象时,它使用打印方法打印“动物”类对象的打印,可能是print.default。另一方面,isS4测试S表达式是否为S4SXP。所以你们每个人都有...
强制,也许通过将releventsetAs
函数实现, using
为(obj,“ animal”)`。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句