我看见:
"为了理解R中的计算,两个口号是有帮助的:
•存在的一切都是一个对象.
•发生的一切都是函数调用."- 约翰钱伯斯
但我刚刚发现:
a <- 2
is.object(a)
# FALSE
Run Code Online (Sandbox Code Playgroud)
实际上,如果变量是纯基类型,那么结果是.object()将为FALSE.所以它不应该是一个对象.
那么R中"存在的一切是一个对象"的真正含义是什么?
Car*_*lli 23
该函数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
Run Code Online (Sandbox Code Playgroud)
现在,试着回答你真实的问题,关于口号,这就是我要说的.存在的所有东西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)
Run Code Online (Sandbox Code Playgroud)
或者采取一种功能,例如rnorm:
rnorm
function (n, mean = 0, sd = 1)
.Call(C_rnorm, n, mean, sd)
<environment: namespace:stats>
Run Code Online (Sandbox Code Playgroud)
您可以像简单对象一样更改其默认参数,例如列表:
formals(rnorm)[2] <- 100
rnorm
function (n, mean = 100, sd = 1)
.Call(C_rnorm, n, mean, sd)
<environment: namespace:stats>
Run Code Online (Sandbox Code Playgroud)
再从Chambers(2008)那里再来一次:
关键概念是评估表达本身就是对象; 在S语言的传统座右铭中,一切都是一个对象.评估包括获取表示表达式的对象并返回作为该表达式值的对象.
所以回到我们的调用示例,call是一个代表另一个对象的对象.在评估时,它变成另一个对象,在这种情况下是具有一个数字的数字向量:-0.008138572.
set.seed(1)
eval(call)
[1] -0.008138572
Run Code Online (Sandbox Code Playgroud)
这将把我们带到第二个口号,你没有提到,但通常与第一个口号一起:"发生的一切都是函数调用".
再次从钱伯斯(Chambers)(2008)那里,他实际上对这一陈述进行了一些限定:
几乎R中发生的一切都来自函数调用.因此,基本编程以创建和改进功能为中心.
所以这意味着几乎所有发生的数据转换R都是函数调用.即使是简单的事情,如括号,也是一个功能R.
因此,将括号作为示例,您实际上可以重新定义它来执行以下操作:
`(` <- function(x) x + 1
(1)
[1] 2
Run Code Online (Sandbox Code Playgroud)
这不是一个好主意,但说明了这一点.所以我想这就是我总结的结果:R中存在的所有东西都是一个对象,因为它们是可以被操纵的数据.并且(几乎)发生的所有事情都是函数调用,它是对该对象的评估,它为您提供了另一个对象.
Dir*_*tel 11
我喜欢那句话.
在另一篇(截至目前尚未发表)的文章中,作者继续写道
R具有统一的内部结构,用于表示所有对象.评估过程以简单的形式关闭该结构,该形式主要由函数调用组成,对象作为参数,对象作为值.理解R中对象和函数的核心作用使得该软件对任何具有挑战性的应用程序更有效,即使那些扩展R不是目标的应用程序也是如此.
但随后花了数百页扩展它.一旦完成,这将是一个伟大的阅读.
对象对于x为对象意味着它有一个类从而class(x)返回类为每一个对象.甚至函数都有一个类,环境和其他可能没有预料到的对象:
class(sin)
## [1] "function"
class(.GlobalEnv)
## [1] "environment"
Run Code Online (Sandbox Code Playgroud)
我不会太在意is.object. is.object(x)与我们在这里使用的含义略有不同 - 如果x内部存储了类名及其值,则返回TRUE .如果存储了类,则class(x)返回存储的值,否则class(x)将从类型中计算它.从概念的角度来看,重要的不是类如何在内部存储(存储或计算) - 重要的是在两种情况下x仍然是一个对象并且仍然有一个类.
函数所有计算都是通过函数进行的,这指的是即使是你可能不希望成为函数的东西实际上也是函数.例如,当我们写:
{ 1; 2 }
## [1] 2
if (pi > 0) 2 else 3
## [1] 2
1+2
## [1] 3
Run Code Online (Sandbox Code Playgroud)
我们实际上做的调用{,if以及+功能:
`{`(1, 2)
## [1] 2
`if`(pi > 0, 2, 3)
## [1] 2
`+`(1, 2)
## [1] 3
Run Code Online (Sandbox Code Playgroud)