Почему терминология ярлыков и уровней в факторах настолько странная?
Примером не устанавливаемой функции будет labels
. Вы можете устанавливать метки факторов только тогда, когда они создаются с помощью фактор-функции. Нет функции labels<-
. Не то, чтобы "метки" и "уровни" в факторах имели смысл...
> fac <- factor(1:3, labels=c("one", "two", "three"))
> fac
[1] one two three
Levels: one two three
> labels(fac)
[1] "1" "2" "3"
ОК, я попросил лейблы, которые можно было бы предположить, были установлены множителем, но я получаю что-то совершенно... какое слово, неинтуитивное?
> levels(fac)
[1] "one" "two" "three"
Итак, кажется, что установочные метки действительно устанавливают уровни.
> fac <- factor(1:3, levels=c("one", "two", "three"))
> levels(fac)
[1] "one" "two" "three"
ОК, что и ожидалось. Итак, каковы метки при наборе уровней?
> fac <- factor(1:3, levels=c("one", "two", "three"), labels=c("x","y", "z") )
> labels(fac)
[1] "1" "2" "3"
> levels(fac)
[1] "x" "y" "z"
Эффектно странно, если вы спросите меня. Похоже, что аргументы "меток" для коэффициента trump содержат любые "уровни" аргументов для спецификации уровней. Почему это должно быть? Кажется, это путаная терминология. И почему labels()
возвращает то, что я мог бы себе представить, используя as.character(as.numeric(fac))?
(Это был тангенциальный комментарий [помеченный как таковой] в более раннем ответе о функциях присваивания, на который меня попросили перейти к вопросу. Итак, вот ваша возможность просветить меня.)
Ответы
Ответ 1
Я думаю, что способ думать о различии между labels
и levels
(игнорируя функцию labels()
, которую описывает Томми в своем ответе), состоит в том, что levels
предназначен для того, чтобы рассказать R, какие значения нужно искать в вход (x
) и какой порядок использования на уровнях результирующего объекта factor
и labels
- изменить значения уровней после того, как вход был закодирован как фактор... как это было предложено Ответ Tommy, нет части объекта factor
, возвращаемого factor()
, который называется labels
... только уровни, которые были отрегулированы аргументом labels
... (очистить как грязь).
Например:
> f <- factor(x=c("a","b","c"),levels=c("c","d","e"))
> f
[1] <NA> <NA> c
Levels: c d e
> str(f)
Factor w/ 3 levels "c","d","e": NA NA 1
Поскольку первые два элемента x
не были найдены в levels
, первые два элемента f
равны NA
. Поскольку "d"
и "e"
были включены в levels
, они отображаются на уровнях f
, хотя они не встречались в x
.
Теперь с labels
:
> f <- factor(c("a","b","c"),levels=c("c","d","e"),labels=c("C","D","E"))
> f
[1] <NA> <NA> C
Levels: C D E
После того, как R выясняет, что должно быть в коэффициенте, он перекодирует уровни. Можно, конечно, использовать это, чтобы делать мозговые вещи, такие как:
> f <- factor(c("a","b","c"),levels=c("c","d","e"),labels=c("a","b","c"))
> f
[1] <NA> <NA> a
Levels: a b c
Другой способ думать о levels
заключается в том, что factor(x,levels=L1,labels=L2)
эквивалентен
f <- factor(x,levels=L1)
levels(f) <- L2
Я думаю, что подходящая версия этого примера может быть приятной для Pat Burns R inferno - в разделе 8.2 есть много головоломок-факторов, но не этот конкретный...
Ответ 2
Функция labels
звучит как идеальная подгонка для получения меток фактора.
... но функция labels
не имеет ничего общего с факторами! Он используется как общий способ заставить что-то "наклеить" объект. Для атомных векторов это были бы имена. Но если нет имен, функция labels
возвращает индексы элементов, принудительно привязанные к строкам - что-то вроде as.character(seq_along(x))
.
... Итак, что вы видите, когда вы пытаетесь использовать ярлыки по фактору. Коэффициент представляет собой целочисленный вектор без каких-либо имен, но с атрибутом levels
.
У фактора нет меток. Он имеет только уровни. Аргумент labels
для factor
- это просто способ дать набор строк, но создать другой набор строк в качестве уровней...
Но для того, чтобы еще больше запутать, функция dput
печатает атрибуты levels
как .Label
! Я думаю, что это наследие...
# Translate lower case letters to upper case.
f <- factor(letters[2:4], letters[1:3], LETTERS[1:3])
dput(f)
#structure(c(2L, 3L, NA), .Label = c("A", "B", "C"), class = "factor")
attributes(f)
#$levels
#[1] "A" "B" "C"
#
#$class
#[1] "factor"
Однако, поскольку labels
является общей функцией, вероятно, было бы неплохо определить labels.factor
следующим образом (в настоящее время их нет). Возможно, что-то для ядра R рассмотреть?
labels.factor <- function(x, ...) as.character(x)