is.object 和 S3 类系统

发布于 2024-10-12 22:28:53 字数 521 浏览 4 评论 0原文

使用class函数可以让我们确定一个对象的类:

> x = 5
> class(x)
[1] "numeric"

我也理解我们可以使用is.object命令来确定一个对象是否有一个类。然而,有些对象类型是隐式的,也就是说

> is.object(x)
[1] FALSE

,声明 R 中的所有变量都是对象并且 is.object 仅对非隐式类进行测试是否正确?

另外,类型如何适应这一点。天真地,我认为下面的代码会产生错误:

> x = 5
> class(x) = "fake"
> x = X + 1
> x + 1
[1] 6
attr(,"class")
[1] "fake"

但是 x 仍然具有类型“double”,仍然一切仍然有效。类型可以被认为是所有其他对象继承自的超类吗?

Using the class function allows us to determine the class of an object:

> x = 5
> class(x)
[1] "numeric"

I also understand that we can use the is.object command to determine if an object has a class. However some object types are implicit, that is

> is.object(x)
[1] FALSE

Would it be correct to state that all variables in R are objects and is.object is a test for non-implicit classes only?

Also, how do types fit into this. Naively, I thought that the following piece of code would produce an error:

> x = 5
> class(x) = "fake"
> x = X + 1
> x + 1
[1] 6
attr(,"class")
[1] "fake"

But x still has type "double", still everything still works. Can types be thought of as a superclass that all other objects inherit from?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

贵在坚持 2024-10-19 22:28:53

typeof 返回内部 C 表示的类型,它不用于方法分派。因此严格来说,您不能将类型视为“超类”。

相反,有基本类(数字、字符、列表、函数等),它们大致对应于名称
typeof 返回,但并非总是如此(例如 double 类型属于 numeric 类,special 和closure 属于此类
函数,并且类 data.frame 是列表类型!)。

使用 S3 和 S4 系统,您可以使用基本类构建非平凡的类(但不必扩展其中之一!示例: setClass("foo", list(a="numeric",b="character")< /code> 不扩展任何基本类)。

对于来自这些基本类的对象,is.object 返回 FALSE 正如其文档所述。 ,这个函数提供了
一种非常快速的方法来检查对象是否属于用户构建的 S3 或 S4 类(即不是基本类之一)。

x 转换为“假”后,您的对象正式不属于“数字”类:

is(x, "numeric")
#FALSE

但它可以解释为基本“数字”对象:

is.numeric(x)
#TRUE

这就是 + 在这里工作的原因。因此,在内部,正如 @Richie 所说,默认方法将 x 解释为
数字基础类。

这种概念上的混乱是由于 S3 对类的非正式处理造成的。请改用 S4。


typeof(.) 和 basic class(.) 的对应关系:

                              typeof(.)  class(.)
NULL                          "NULL"     "NULL"
1                             "double"   "numeric"
1:1                           "integer"  "integer"
1i                            "complex"  "complex"
list(1)                       "list"     "list"
data.frame(x=1)               "list"     "data.frame"
pairlist(pi)                  "pairlist" "pairlist"
c                             "special"  "function"
lm                            "closure"  "function"
formals(lm)[[1]]              "symbol"   "name"
formals(lm)[[2]]              "symbol"   "name"
y~x                           "language" "formula"
expression((1))[[1]]          "language" "("
(y~x)[[1]]                    "symbol"   "name"
expression(x <- pi)[[1]][[1]] "symbol"   "name"

typeof returns the type of internal C representation, and it is not used for method dispatch. So strictly speaking you can not think of types as "superclasses".

There are instead basic classes (numeric, character, list, function etc) which roughly correspond to the names
returned by typeof, but not always (for example type double is of class numeric, special and closure are of class
function, and class data.frame is of type list!).

With S3 and S4 systems you can build non trivial classes using basic classes (but not necessary extending one of those!! example: setClass("foo", list(a="numeric",b="character") does not extend any of the basic classes).

For objects from these basic classes is.object returns FALSE. As its documentation says, this function provides
a very fast way to check if the object is of user build S3 or S4 class (i.e. not one of basic classes).

After casting x as "fake" your object is formally not of "numeric" class:

is(x, "numeric")
#FALSE

but it is interpretable as basic "numeric" object:

is.numeric(x)
#TRUE

And this is why + works here. So, internally, as @Richie already said the default method interprets x as of
numeric basic class.

This conceptual mess is because of S3 informal treatment of classes. Use S4 instead.


correspondence between typeof(.) and basic class(.):

                              typeof(.)  class(.)
NULL                          "NULL"     "NULL"
1                             "double"   "numeric"
1:1                           "integer"  "integer"
1i                            "complex"  "complex"
list(1)                       "list"     "list"
data.frame(x=1)               "list"     "data.frame"
pairlist(pi)                  "pairlist" "pairlist"
c                             "special"  "function"
lm                            "closure"  "function"
formals(lm)[[1]]              "symbol"   "name"
formals(lm)[[2]]              "symbol"   "name"
y~x                           "language" "formula"
expression((1))[[1]]          "language" "("
(y~x)[[1]]                    "symbol"   "name"
expression(x <- pi)[[1]][[1]] "symbol"   "name"
以可爱出名 2024-10-19 22:28:53

第一个问题的部分答案可以在 R 语言定义的第二章中找到

R 不提供直接访问
而是计算机的内存
提供大量专业数据
我们将称为的结构
对象。这些对象被引用
通过符号或变量。在 R 中,
然而,这些符号本身就是
对象并可以在
与任何其他对象一样。

所以,是的,所有变量都是对象。

is.object 似乎或多或少相当于 function(x) !is.null(attr(x, "class")) 但我愿意事实证明这一点是错误的。

至于第二个问题,我认为是这样的:
由于x有类“fake”,R在加法中寻找方法+.fake,但当找不到时,它会求助于默认方法。该默认方法基于底层 C 代码,它使用 typeof(x) (或 C 等效项)来确定应该做什么。在这种情况下,x 的类型是“整数”。

A partial answer to the first question is found in Chapter 2 of the R language defninition

R does not provide direct access to
the computer’s memory but rather
provides a number of specialized data
structures we will refer to as
objects. These objects are referred to
through symbols or variables. In R,
however, the symbols are themselves
objects and can be manipulated in the
same way as any other object.

So, yes, all variables are objects.

is.object seems to be more or less equivalent to function(x) !is.null(attr(x, "class")) but I'm willing to be proved wrong on that.

As for the second question, I think this is what happens:
Since x has class "fake", R looks for a method +.fake in the addition but when it doesn't find one, it resorts to the default method. That default method is based upon underlying C code, which uses typeof(x) (or a C equivalent) to determine what should be done. In this case the type of x is "integer".

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文