is.object и система класса S3
Вопрос
С использованием 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", все еще все еще работает. Можно ли рассматривать типы как суперкласса, от которого наследуют все другие объекты?
Решение
typeof
Возвращает тип внутреннего представления C, и оно не используется для отправки метода. Так строго говоря, вы не можете думать о типах как о «суперклассах».
Вместо этого есть Основные классы (числовой, символ, список, функция и т. Д.), что примерно соответствует именам, возвращаемым typeof
, но не всегда (например, тип Double имеет класс числовое, специальное и закрытие функции класса, а данные класса. 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(.) 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 Defninition Rangue R
R не предоставляет прямой доступ к памяти компьютера, а скорее предоставляет ряд специализированных структур данных, которые мы будем называть объектами. Эти объекты упоминаются через символы или переменные. В R, однако, символами сами являются объектами и могут манипулировать таким же образом, как и любой другой объект.
Итак, да, все переменные - это объекты.
is.object
кажется более или менее эквивалентным function(x) !is.null(attr(x, "class"))
Но я готов быть ошибочным в этом.
Что касается второго вопроса, я думаю, что это то, что происходит: с x
Имеет класс «подделка», R ищет метод +.fake
В дополнение, но когда он не найдет его, он прибегает к методу по умолчанию. Этот метод по умолчанию основан на базовом коде C, который использует typeof(x)
(или C, эквивалентный), чтобы определить, что должно быть сделано. В этом случае тип x
«целое число».