Подтвердить что ты не робот

Какое истинное значение "Все, что существует, является объектом" в R?

Я видел:

"Чтобы понять вычисления в R, полезны два лозунга:

• Все, что существует, является объектом.
  • Все, что происходит, это вызов функции.

- Джон Чемберс

Но я только что нашел:

a <- 2
is.object(a)
# FALSE

На самом деле, если переменная является чистым базовым типом, то результат is.object() будет FALSE. Поэтому он не должен быть объектом.

Итак, каков реальный смысл "Все, что существует, является объектом" в R?

4b9b3361

Ответ 1

Функция is.object выглядит только для того, чтобы объект имел атрибут "class". Таким образом, это не то же значение, что и в слогане.

Например:

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, является объектом, потому что это данные, которыми можно манипулировать. И (почти) все, что происходит, это вызов функции, который является оценкой этого объекта, который дает вам другой объект.

Ответ 2

Мне нравится эта цитата.

В другом (на данный момент неопубликованном) написании, автор продолжает

R имеет единую внутреннюю структуру для представления всех объектов. Процесс оценки отбрасывает эту структуру в простой форме, которая по существу состоящий из вызовов функций, с объектами в качестве аргументов и объектом в качестве стоимость. Понимание центральной роли объектов и функций в R делает использование программного обеспечения более эффективно для любого сложного приложения, даже те, где расширение R не является целью.

но затем тратит на него несколько сотен страниц. Это будет великолепное чтение после завершения.

Ответ 3

Объекты Для x, чтобы быть объектом, означает, что у него есть класс, поэтому class(x) возвращает класс для каждого объекта. Даже функции имеют класс, как и среды, и другие объекты, которые можно не ожидать:

class(sin)
## [1] "function"

class(.GlobalEnv)
## [1] "environment"

Я бы не обратил слишком много внимания на is.object. is.object(x) имеет немного другое значение, чем то, что мы здесь используем, - оно возвращает TRUE, если x имеет внутреннее хранилище и его значение. Если класс сохраняется, то class(x) возвращает сохраненное значение, а если нет, то class(x) будет вычислять его из этого типа. С концептуальной точки зрения важно не то, как класс представлен внутри (хранится или computerd) - важно то, что в обоих случаях x все еще является объектом и все еще имеет класс.

Функции. Все вычисления, выполняемые через функции, относятся к тому факту, что даже функции, которые вы не можете ожидать, являются функциями. Например, когда мы пишем:

{ 1; 2 }
## [1] 2

if (pi > 0) 2 else 3
## [1] 2

1+2
## [1] 3

мы фактически делаем вызовы функций {, if и +:

`{`(1, 2)
## [1] 2

`if`(pi > 0, 2, 3)
## [1] 2

`+`(1, 2)
## [1] 3