功能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
是一个对象,因为它是一种可以操作的数据结构。我认为通过函数和表达式可以更好地理解这一点,它们通常不被视为数据。
引用Chambers (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>
再次引用Chambers (2008) 的一段话:
关键概念是求值表达式本身
物体;在 S 语言的传统座右铭中,一切都是一个
目的。评估包括获取代表某个对象的对象
表达式并返回该值的对象
表达。
回到我们的调用示例,call
是一个代表另一个对象的对象。求值时,它变成另一个对象,在本例中是具有一个数字的数值向量:-0.008138572。
set.seed(1)
eval(call)
[1] -0.008138572
这将把我们带到第二个口号,你没有提到,但通常与第一个口号一起出现:“发生的一切都是函数调用”。
再次引用 Chambers (2008) 的观点,他实际上对这一说法做了一些限定:
R 中发生的几乎所有事情都是由函数调用产生的。
因此,基础编程的重点是创建和完善
功能。
所以这意味着几乎所有发生的数据转换R
是一个函数调用。即使是一个简单的东西,比如括号,也是一个函数R
.
因此,以括号为例,您实际上可以重新定义它来执行以下操作:
`(` <- function(x) x + 1
(1)
[1] 2
这不是一个好主意,但说明了这一点。所以我想这就是我的总结:R 中存在的一切都是对象,因为它们是可以操作的数据。而且(几乎)发生的所有事情都是函数调用,这是对该对象的评估,它为您提供另一个对象。