函数is.object 似乎只查看对象是否具有“类”属性。所以和标语里的意思不一样。
例如:
x <- 1
attributes(x) # it does not have a class attribute
NULL
is.object(x)
[1] FALSE
class(x) <- "my_class"
attributes(x) # now it has a class attribute
$class
[1] "my_class"
is.object(x)
[1] TRUE
现在,试着回答你真正的问题,关于口号,我会这样说。 R 中存在的一切都是对象,因为它是一种可以操作的数据结构。我认为用函数和表达式可以更好地理解这一点,它们通常不被认为是数据。
引用钱伯斯 (2008) 的话:
R 中的核心计算是一个函数调用,由
函数对象本身和作为
论据。在函数式编程模型中,定义了结果
由另一个对象调用的值。因此,传统的座右铭
S 语言:一切都是对象——参数、值、
实际上是函数和调用本身:所有这些都是定义的
作为对象。将对象视为各种数据的集合。包含的数据和数据的组织方式取决于生成对象的类。
以这个表达式为例mean(rnorm(100), trim = 0.9)。在它被评估之前,它是一个非常像任何其他对象的对象。因此,您可以像使用列表一样更改其元素。例如:
call <- substitute(mean(rnorm(100), trim = 0.9))
call[[2]] <- substitute(rt(100,2 ))
call
mean(rt(100, 2), trim = 0.9)
或者取一个函数,比如rnorm:
rnorm
function (n, mean = 0, sd = 1)
.Call(C_rnorm, n, mean, sd)
<environment: namespace:stats>
你可以像一个简单的对象一样改变它的默认参数,也像一个列表:
formals(rnorm)[2] <- 100
rnorm
function (n, mean = 100, sd = 1)
.Call(C_rnorm, n, mean, sd)
<environment: namespace:stats>
《钱伯斯》(2008 年)再看一次:
关键概念是评估表达式本身
物体;在 S 语言的传统格言中,一切都是
目的。评估包括取代表一个对象的对象
表达式并返回作为该值的对象
表达。
回到我们的调用示例,call 是一个代表另一个对象的对象。评估时,它变成另一个对象,在这种情况下是具有一个数字的数字向量:-0.008138572。
set.seed(1)
eval(call)
[1] -0.008138572
这将把我们带到第二个口号,你没有提到它,但通常与第一个口号一起出现:“发生的一切都是函数调用”。
再次引用钱伯斯(2008),他实际上有点限定了这个陈述:
R 中发生的几乎所有事情都来自函数调用。
因此,基本的编程以创建和改进为中心
功能。
这意味着R 中发生的几乎所有数据转换都是一个函数调用。即使是简单的东西,比如括号,也是R中的一个函数。
因此,以括号为例,您实际上可以重新定义它以执行以下操作:
`(` <- function(x) x + 1
(1)
[1] 2
这不是一个好主意,但说明了这一点。所以我想这就是我的总结:R中存在的一切都是一个对象,因为它们是可以操作的数据。并且(几乎)所有发生的事情都是一个函数调用,这是对这个对象的评估,它为您提供另一个对象。