2014-10-28 3 views
2

Я относительно новичок в R. При чтении документов следующее предложение меня смущает.Когда is is.vector() возвращает true?

is.vector() не проверяет, является ли объект вектором. Вместо этого он возвращает TRUE только в том случае, если объект является вектором без атрибутов, кроме имен.

other thread о том, почему is.vector() return TRUE для списка может быть хорошей ссылкой.

Когда is.vector() return true?

ответ

2

Некоторые примеры для разных типов данных.

x <- list(
    "integer vector" = integer(), 
    "numeric vector" = numeric(), 
    "character vector" = character(), 
    "logical vector" = logical(), 
    "complex vector" = complex(), 
    "raw vector"  = raw(), 
    list    = list(), 
    expression   = expression(), 
    factor    = factor(), 
    pairlist   = pairlist(), 
    "numeric matrix" = matrix(1), 
    "character matrix" = matrix("a"), 
    data.frame   = data.frame(), 
    formula   = y ~ x, 
    "function"   = identity, 
    call    = call("identity", 1), 
    name    = as.name("a"), 
    null    = NULL, 
    environment  = new.env() 
) 
vapply(x, is.vector, logical(1)) 
## integer vector numeric vector character vector logical vector 
##    TRUE    TRUE    TRUE    TRUE 
## complex vector  raw vector    list  expression 
##    TRUE    TRUE    TRUE    TRUE 
##   factor   pairlist numeric matrix character matrix 
##    FALSE   FALSE   FALSE   FALSE 
##  data.frame   formula   function    call 
##    FALSE   FALSE   FALSE   FALSE 
##    name    null  environment 
##    FALSE   FALSE   FALSE 

Результаты factor и list не совсем интуитивно, поэтому будьте осторожны с ними. Часто вы хотите is.atomic, а не is.vector.

+0

+1 для 'is.atomic'. – shadowtalker

2

is.vector() не проверяет, является ли объект вектором. Вместо этого он возвращает TRUE, только если объект является вектором без атрибутов, кроме имен.

Цитата означает, что именно он говорит. Почему говорит, что он говорит более тонко.

Все объекты R связаны со списком «атрибутов», с возможностью просмотра с attributes() (для всего списка) с attr() (для отдельных атрибутов). На самом деле, класс объекта - это просто специальный атрибут, который используют общие функции (S3) для определения того, какой метод использовать.

Это свойство имеет тенденцию быть «тихим» в большинстве случаев, но видно с выходом функции na.omit() (попробуйте x <- c(1, NA); y <- na.omit(x); print(y), чтобы посмотреть, как это может выглядеть). Здесь y имеет один атрибут, na.action, который сам по себе является объектом с атрибутом, class. Назначьте этот атрибут отдельному объекту с помощью z <- attr(y, "na.action") и посмотрите его атрибуты с помощью attributes(z), а затем attr(z, "class").

Когда существует атрибут class, R использует его для перезаписывания класса базового объекта; в этом случае класс omit переопределяет внутренний класс integer. Попробуйте attr(z, "class") <- NULL; class(z). Обратите внимание, что это тот же результат, что и прямое письмо class(z) <- NULL.

Теперь назначьте z z <- attr(y, "na.action") еще раз. Попробуйте is.vector(z). Затем снова удалите его класс с NULL и снова попробуйте is.vector(z). Надеюсь, это должно дать понять, что проверяет is.vector. Тот факт, что атрибут class имеет специальное назначение при отправке метода, не имеет значения. Фактически, вы можете сделать то же самое для y: попробуйте is.vector(y), is.vector(x[!is.na(x)]).

Причиной этого критерия является то, что многие объекты в R, которые не выглядят или действуют как векторы, хранятся внутри как векторы. Матрицы входят в эту категорию. Попробуйте что-то вроде x <- matrix(1:4, 2); dput(x).Вы заметите, что x сохраняется как вектор1:4 со специальным атрибутом .Dim. Этот атрибут скрыт и недоступен; попробуйте attr(x, ".Dim").

Все это задокументировано где-то в руководстве R (где я впервые увидел его), но я не помню, в каком разделе.