Факторы — категориальные данные

Знакомимся с типом factor — особым способом хранить категории вроде пола, города или оценки.

Фактор (factor) — тип данных для категориальных переменных: значений из ограниченного набора категорий.

Некоторые данные — это не числа и не произвольный текст, а категории: «мужской/женский», «низкий/средний/высокий», «понедельник…воскресенье». Хранить их как обычные строки можно, но R предлагает специальный тип — factor, который знает список допустимых категорий и эффективнее хранится.

Зачем нужен отдельный тип, если есть строки? Во-первых, фактор фиксирует набор допустимых значений: если в данные затесалась опечатка «Мсква», она станет отдельным уровнем — и вы сразу это заметите. Во-вторых, многие статистические функции и графики ggplot2 ведут себя по-разному со строками и факторами: фактор задаёт порядок столбцов на диаграмме, группы в регрессии, легенду на графике. В-третьих, при больших данных факторы экономят память. Поэтому категориальные переменные принято хранить именно факторами.

Создание фактора

Фактор создаётся функцией factor из вектора строк:

grades <- factor(c("средний", "низкий", "высокий", "средний"))
grades

Вывод:

[1] средний низкий  высокий средний
Levels: высокий низкий средний

R автоматически определил три уровня (levels) — уникальные категории. По умолчанию они идут в алфавитном порядке, что не всегда логично для «низкий/средний/высокий».

Упорядоченные факторы

Если у категорий есть естественный порядок, его задают явно через ordered = TRUE и аргумент levels:

grades <- factor(
  c("средний", "низкий", "высокий"),
  levels = c("низкий", "средний", "высокий"),
  ordered = TRUE
)
grades[1] > grades[2]

Вывод:

[1] TRUE

Теперь R понимает, что «средний» больше «низкого», и сравнения работают правильно.

Подсчёт категорий

Функция table мгновенно строит частотную таблицу — сколько раз встретилась каждая категория:

city <- factor(c("Москва", "Казань", "Москва", "Москва", "Казань"))
table(city)

Вывод:

city
Казань Москва 
     2      3 

Как работает под капотом

Внутри фактор хранится не как строки, а как целые числа-коды плюс отдельный словарь уровней. Например, «низкий/средний/высокий» хранятся как 1, 2, 3, а подписи лежат в атрибуте levels. Это экономит память при больших данных и ускоряет работу. Из-за этого есть ловушка: если попытаться превратить фактор в число через as.numeric, вы получите коды уровней (1, 2, 3), а не исходные значения.

Частые ошибки

  • Полагаться на алфавитный порядок. Для упорядоченных категорий задавайте levels вручную.
  • as.numeric на факторе. Вернёт коды, а не значения. Для чисел сначала переведите в строки: as.numeric(as.character(f)).
  • Превращать в фактор то, что является числом. Возраст и доход — это numeric, а не категории.

Итог

  • Фактор — тип для категориальных данных с фиксированным набором уровней.
  • Уровни задаются автоматически (по алфавиту) или вручную через levels.
  • ordered = TRUE делает категории сравнимыми.
  • table() считает частоты категорий.
Проверьте себя
1. Для каких данных предназначен тип factor?
AДля дробных чисел
BДля категориальных данных из ограниченного набора
CДля дат
DДля произвольного длинного текста
2. Как задать естественный порядок категорий «низкий < средний < высокий»?
AНикак, всегда алфавит
BЧерез аргументы levels и ordered = TRUE
CЧерез sort()
DЧерез as.numeric()
3. Что вернёт as.numeric() для фактора?
AИсходные числовые значения
BКоды уровней (1, 2, 3...)
CОшибку
DСтроки