gpt4 book ai didi

r - 使用类函数更改 S4 对象的 "class"时发生了什么?

转载 作者:行者123 更新时间:2023-12-04 11:11:59 25 4
gpt4 key购买 nike

如果我有一个 S4 类(class),例如:

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,并附有属性列表。

通过使用 S3-ism class<-正如@hadley 指出的那样,你创造了一个混合怪物。 class<-仅更新类属性,而不会更改底层 S4SXP。当您打印对象时,它使用“动物”类对象的打印方法打印,可能是print.default。另一方面,isS4 测试 S 表达式是否是 S4SXP,它是。所以你有一些...

强制,也许是通过实现相关的 setAs功能 , using as(obj,“动物”)`。

关于r - 使用类函数更改 S4 对象的 "class"时发生了什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23543368/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com