Путаница между уровнями факторов и метками факторов

106

Кажется, есть разница между уровнями и метками фактора в R. До сих пор я всегда думал, что уровни были `` настоящим '' именем уровней факторов, а метки были именами, используемыми для вывода (например, таблиц и графиков) . Очевидно, что это не так, как показывает следующий пример:

df <- data.frame(v=c(1,2,3),f=c('a','b','c'))
str(df)
'data.frame':   3 obs. of  2 variables:
 $ v: num  1 2 3
 $ f: Factor w/ 3 levels "a","b","c": 1 2 3

df$f <- factor(df$f, levels=c('a','b','c'),
  labels=c('Treatment A: XYZ','Treatment B: YZX','Treatment C: ZYX'))
levels(df$f)
[1] "Treatment A: XYZ" "Treatment B: YZX" "Treatment C: ZYX"

Я думал, что уровни ('a', 'b', 'c') каким-то образом могут быть доступны при написании скриптов, но это не работает:

> df$f=='a'
[1] FALSE FALSE FALSE

Но это действительно так:

> df$f=='Treatment A: XYZ' 
[1]  TRUE FALSE FALSE

Итак, мой вопрос состоит из двух частей:

  • В чем разница между уровнями и ярлыками?

  • Можно ли иметь разные имена для уровней факторов для написания сценариев и вывода?

Предпосылки: Для более длинных сценариев создание сценариев с короткими уровнями факторов кажется намного проще. Однако для отчетов и графиков эти короткие уровни факторов могут не подходить, и их следует заменить более точными названиями.

Donodarazao
источник

Ответы:

131

Очень коротко: уровни - это вход, метки - это выход в factor()функции. Фактор имеет только levelатрибут, который задается labelsаргументом factor()функции. Это отличается от концепции меток в статистических пакетах, таких как SPSS, и может сбивать с толку вначале.

Что вы делаете в этой строке кода

df$f <- factor(df$f, levels=c('a','b','c'),
  labels=c('Treatment A: XYZ','Treatment B: YZX','Treatment C: ZYX'))

сообщает R, что существует вектор df$f

  • который вы хотите превратить в фактор,
  • в котором разные уровни кодируются как a, b и c
  • и для которых вы хотите, чтобы уровни были помечены как Лечение А и т. д.

Функция фактора будет искать значения a, b и c, преобразовывать их в числовые классы факторов и добавлять значения меток к levelатрибуту фактора. Этот атрибут используется для преобразования внутренних числовых значений в правильные метки. Но, как видите, labelатрибута нет .

> df <- data.frame(v=c(1,2,3),f=c('a','b','c'))    
> attributes(df$f)
$levels
[1] "a" "b" "c"

$class
[1] "factor"

> df$f <- factor(df$f, levels=c('a','b','c'),
+   labels=c('Treatment A: XYZ','Treatment B: YZX','Treatment C: ZYX'))    
> attributes(df$f)
$levels
[1] "Treatment A: XYZ" "Treatment B: YZX" "Treatment C: ZYX"

$class
[1] "factor"
Джорис Мейс
источник
1
Спасибо за быстрый ответ! Думаю, теперь я понимаю назначение уровней и меток. Может быть, есть какие-нибудь предложения по улучшению читабельности вывода без ручного редактирования имен таблиц и легенд?
donodarazao
6
Я часто трансформировал уровни прямо перед построением / созданием меток, например, сохранял уровни как «a», «b», «c» во время манипулирования, затем использовал уровни (f) <- paste («Лечение», toupper (levels ( f)), sep = "") [или что-то в этом роде] при построении графика. Или создайте параллельный коэффициент f_pretty, который вы носите с собой и используете только для вывода ...
Бен Болкер
Я думал об обоих, но у обоих есть недостатки. Первый может быть утомительным при построении огромного количества графиков, а второй может стать утомительным, когда в сценарии задействовано много агрегирования данных. Но, очевидно, этого легко избежать, поэтому я приму ваши предложения. :)
donodarazao
@ 42- Я не совсем понимаю, что вы имеете в виду под "числовыми значениями". Если вы имеете в виду внутренние значения фактора, то это именно то, что я сказал выше. Отсюда и упоминание внутренних числовых значений. Если вы указываете levelsаргумент, вы даете значения во входных данных, которые должны быть сопоставлены с labelsаргументом. R сохраняет метки (как атрибут levels, и здесь возникает путаница) и хранит целочисленные коды внутри. Эти целочисленные коды не имеют ничего общего с исходными значениями, какого бы типа они ни были. Я думаю, вы меня неправильно поняли.
Joris Meys
Извинения. То, что вы пишете, также было моим пониманием, и теперь, когда я перечитываю ваш вопрос, я не вижу, где, как я думал, вы сказали иначе. Я удалю свой комментарий, потому что он добавляет меньше, чем ничего.
IRTFM 03
17

Я написал пакет lfactors, который позволяет ссылаться либо на уровни, либо на метки.

# packages
install.packages("lfactors")
require(lfactors)

flips <- lfactor(c(0,1,1,0,0,1), levels=0:1, labels=c("Tails", "Heads"))
# Tails can now be referred to as, "Tails" or 0
# These two lines return the same result
flips == "Tails"
#[1]  TRUE FALSE FALSE  TRUE  TRUE FALSE
flips == 0 
#[1]  TRUE FALSE FALSE  TRUE  TRUE FALSE

Обратите внимание, что lfactor требует, чтобы уровни были числовыми, чтобы их нельзя было спутать с метками.

PDB
источник
3
это хороший пакет, спасибо, что опубликовали (и написали) о нем. Кажется, такая функциональность должна быть присуща R-факторам - приятно видеть пакет, который предоставляет такого рода сопоставление пар имя-значение со встроенными проверками эквивалентности.
Soren