题
使用 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
仍然有“双重”类型,但一切仍然有效。可以将类型视为所有其他对象都继承的超类吗?
解决方案
typeof
返回内部C表示的类型,并且不用于方法调度。因此,严格来说,您不能将类型视为“超类”。
相反 基本课程 (数字,字符,列表,功能等),大致对应于由 typeof
, ,但并非总是如此(例如,键入double是类数字,特殊和闭合是类函数的,class data.frame是类型列表!)。
使用S3和S4系统,您可以使用基本类构建非琐碎类(但没有必要扩展其中一个!示例: setClass("foo", list(a="numeric",b="character")
不会扩展任何 基本课程).
对于这些基本类的对象 is.object
返回 FALSE
. 。正如其文档所述,此功能提供了一种非常快速的方法来检查对象是否是用户构建S3或S4类(即不是基本类之一)。
铸造后 x
因为“假”您的对象正式不是“数字”类:
is(x, "numeric")
#FALSE
但是它可以解释为基本的“数字”对象:
is.numeric(x)
#TRUE
这就是为什么 +
在这里工作。因此,在内部,正如@richie已经说过的默认方法解释 x
作为数字基本类。
这种概念混乱是由于S3非正式治疗课程。改用S4。
类型(。)和基本类(。)之间的对应关系:
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"
其他提示
对第一个问题的部分答案是在R语言Defniention的第2章中找到的
R不提供对计算机内存的直接访问,而是提供许多我们将称为对象的专门数据结构。这些对象是通过符号或变量引用的。但是,在r中,符号本身就是对象,并且可以像其他任何对象一样操作。
因此,是的,所有变量都是对象。
is.object
似乎或多或少等同于 function(x) !is.null(attr(x, "class"))
但是我愿意在这方面被证明是错误的。
至于第二个问题,我认为这就是发生的事情:因为 x
有“假”,R寻找方法 +.fake
在加法中,但是当它找不到一个时,它求助于默认方法。该默认方法基于基础C代码,该代码使用 typeof(x)
(或等同的c)确定应该做什么。在这种情况下 x
是“整数”。