mutate: новые колонки

Учимся добавлять и пересчитывать колонки таблицы с помощью mutate.

mutate — глагол dplyr, который добавляет в таблицу новые колонки или изменяет существующие.

Анализ часто требует производных величин: цена с НДС, возраст в месяцах, категория «взрослый/ребёнок», доля от суммы, разница между колонками. mutate вычисляет такие колонки на основе уже имеющихся, не трогая исходные данные.

Это отдельный, важный для анализа этап — конструирование признаков (feature engineering). Сырые данные редко содержат именно те величины, которые нужны для выводов или модели; их приходится выводить из имеющихся. mutate делает это аккуратно: результат — новая таблица, исходная остаётся нетронутой, поэтому эксперименты безопасны. А поскольку вычисления векторные, даже на миллионе строк новая колонка считается мгновенно.

Простое вычисление

Добавим колонку с возрастом в месяцах:

library(dplyr)
people <- mutate(people, age_months = age * 12)

Слева от = — имя новой колонки, справа — выражение. Оно вычисляется векторно для каждой строки. Если имя совпадает с существующей колонкой, она перезапишется.

Условные колонки: if_else

Функция if_else создаёт колонку по условию — «если…, то…, иначе…»:

people <- mutate(
  people,
  status = if_else(age >= 18, "взрослый", "ребёнок")
)

Для каждой строки проверяется age >= 18: где истина — «взрослый», где ложь — «ребёнок».

Несколько условий: case_when

Когда вариантов больше двух, удобнее case_when:

people <- mutate(
  people,
  group = case_when(
    age < 18  ~ "подросток",
    age < 65  ~ "взрослый",
    TRUE      ~ "пенсионер"
  )
)

Условия проверяются сверху вниз; первое сработавшее даёт значение. Последняя строка TRUE ~ ... — это «все остальные случаи».

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

Внутри mutate выражение справа от = вычисляется как операция над целыми векторами-колонками, а не построчно в цикле. Поэтому age * 12 мгновенно пересчитывает всю колонку. Важно отличать if_else из dplyr от базового ifelse: первый строже к типам (обе ветки должны быть одного типа) и аккуратнее с пропусками, что помогает ловить ошибки раньше.

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

  • Использовать if вместо if_else. Обычный if работает с одним значением, а не с вектором-колонкой. Для колонок нужен if_else или case_when.
  • Разные типы в ветках if_else. Нельзя в одной ветке число, в другой строку.
  • Забыть TRUE ~ в case_when. Тогда неучтённые случаи получат NA.

Итог

  • mutate добавляет или меняет колонки на основе вычислений.
  • if_else(условие, да, нет) — два варианта.
  • case_when — много условий, проверяются сверху вниз.
  • Вычисления векторные: применяются ко всей колонке сразу.
Проверьте себя
1. Что делает mutate в dplyr?
AУдаляет строки
BДобавляет или изменяет колонки
CСортирует данные
DЧитает CSV
2. Какую функцию выбрать для колонки с более чем двумя вариантами по условиям?
Aif
Bif_else
Ccase_when
Dswitch
3. Зачем в case_when пишут последнюю строку TRUE ~ "..."?
AЭто обязательная синтаксическая заглушка
BЧтобы задать значение для всех остальных случаев
CЧтобы остановить вычисление
DЧтобы вернуть TRUE