Понимание разницы между attr (x, "class") и class (x) - PullRequest
0 голосов
/ 23 февраля 2019

Фон

Я смотрю на пакет jazz , предложенный Роменом Франсуа.Ромен определяет функцию is_bare_vector со следующим синтаксисом:

is_bare_vector <- function(x) {
  is_vector(x) && !is.object(x) && is.null(attr(x, "class"))
}

Вопрос

Для: x <- 1:

attr(x, "class")
# NULL

Принимая во внимание:

class(x)
# [1] "numeric"

Я хочу понять, почему эти две функции дают разные ответы? Справка по ?attr ссылкам ?class

?attr

Обратите внимание, что некоторые атрибуты (а именно class, comment, dim, dimnames, names, row.names и tsp) обрабатываются специально и имеют ограничения на значения, которые можно установить.(Обратите внимание, что это не так для уровней, которые должны быть установлены для факторов с помощью функции замены уровней.)

?class

Многие объекты R имеют атрибут классасимвольный вектор, дающий имена классов, от которых наследуется объект.(Функции oldClass и oldClass<- получают и устанавливают атрибут, что также может быть сделано напрямую.)

1 Ответ

0 голосов
/ 23 февраля 2019

Вам просто нужно прочитать немного дальше в help("class"):

Если у объекта нет атрибута класса, у него есть неявный класс, а именно «матрица», «массив», "function" или "numeric" или результат typeof (x) (который аналогичен mode (x))

Очевидно, class() также возвратит неявный класс, если атрибут class равенNULL;давайте рассмотрим исходный код C - мы видим, что если атрибут class имеет длину 0, он получает неявный class.:

SEXP R_data_class(SEXP obj, Rboolean singleString)
{
    SEXP value, klass = getAttrib(obj, R_ClassSymbol);
    int n = length(klass);
    if(n == 1 || (n > 0 && !singleString))
    return(klass);
    if(n == 0) {
    SEXP dim = getAttrib(obj, R_DimSymbol);
    int nd = length(dim);
    if(nd > 0) {
        if(nd == 2)
        klass = mkChar("matrix");
        else
        klass = mkChar("array");
    }
    else {
      SEXPTYPE t = TYPEOF(obj);
      switch(t) {
      case CLOSXP: case SPECIALSXP: case BUILTINSXP:
        klass = mkChar("function");
        break;
      case REALSXP:
        klass = mkChar("numeric");
        break;
      case SYMSXP:
        klass = mkChar("name");
        break;
      case LANGSXP:
        klass = lang2str(obj, t);
        break;
      default:
        klass = type2str(t);
      }
    }
    }
    else
    klass = asChar(klass);
    PROTECT(klass);
    value = ScalarString(klass);
    UNPROTECT(1);
    return value;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...