is.object и система классов S3 - PullRequest
4 голосов
/ 18 января 2011

Использование функции 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 все еще имеет тип "double", но все еще все работает.Можно ли считать типы суперклассом, от которого наследуются все другие объекты?

Ответы [ 2 ]

2 голосов
/ 19 января 2011

typeof возвращает тип внутреннего представления C и не используется для отправки метода.Строго говоря, вы не можете думать о типах как о «суперклассах».

Вместо этого базовые классы (числовой, символьный, список, функция и т. Д.), Которые примерно соответствуют именам, возвращаемым typeof, но не всегда (например, тип double имеет числовой класс, special и замыкание имеют функцию класса, а класс 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 (.) И базовым классом (.):

                              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"
2 голосов
/ 18 января 2011

Частичный ответ на первый вопрос находится в Главе 2 определения языка R

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

Так что, да, все переменные являются объектами.

is.object кажется более или менее эквивалентным function(x) !is.null(attr(x, "class")), но я готов ошибиться в этом.

Что касается второго вопроса, я думаю, это то, что происходит: Поскольку x имеет класс "fake", R ищет в добавлении метод +.fake, но когда он не находит его, он прибегает к методу по умолчанию.Этот метод по умолчанию основан на базовом коде C, который использует typeof(x) (или эквивалент C) для определения того, что должно быть сделано.В этом случае тип x является "целым числом".

...