group_by и summarise: агрегация

Учимся считать статистики по группам — средний возраст по городам, выручку по категориям и т.п.

group_by + summarise — связка dplyr для агрегации: разбить таблицу на группы и посчитать сводку по каждой.

Один из самых частых вопросов к данным — «а как по группам?». Средний чек по городам, число заказов по месяцам, продажи по категориям. В dplyr это две функции: group_by объявляет группы, summarise считает по ним сводки.

Этот приём — сердце разведочного анализа. Общее среднее по всей таблице часто бесполезно: оно скрывает различия между сегментами. По-настоящему интересны именно разрезы: где выше зарплаты, в каком месяце просел спрос, какая категория товаров приносит больше. Связка group_by + summarise отвечает на такие вопросы одной короткой цепочкой и заменяет ручные сводные таблицы Excel — но воспроизводимо и без мышки.

summarise без групп

Сначала — сводка по всей таблице. summarise схлопывает множество строк в одну итоговую:

library(dplyr)
people %>%
  summarise(
    avg_age = mean(age),
    n = n()
  )

Вывод:

  avg_age  n
1   25.67  3

Функция n() возвращает число строк в группе (или во всей таблице, если групп нет).

Сила в group_by

Добавим group_by(city) — и тот же summarise посчитается отдельно для каждого города:

people %>%
  group_by(city) %>%
  summarise(
    avg_age = mean(age),
    count = n()
  )

Вывод:

# A tibble: 2 x 3
  city   avg_age count
  <chr>    <dbl> <int>
1 Казань      30     1
2 Москва      23.5   2

Одна строка результата на каждый город. Это и есть аналог сводных таблиц Excel, но в коде и воспроизводимо.

Типичные агрегаты

ФункцияЧто считает
mean(x)среднее
sum(x)сумму
median(x)медиану
n()число строк
n_distinct(x)число уникальных

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

group_by сам по себе ничего не считает — он лишь помечает таблицу, мысленно разрезая её на части по значениям колонки. Реальные вычисления делает summarise: он применяет агрегатную функцию к каждой группе по отдельности и собирает по одной строке-итогу на группу. После summarise одна группировка «снимается». Если в данных есть пропуски, не забудьте mean(age, na.rm = TRUE) — иначе группа с NA даст NA.

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

  • Забыть group_by. Тогда summarise посчитает одну общую сводку, а не по группам.
  • Использовать mutate вместо summarise для итогов. mutate сохраняет все строки, а summarise схлопывает их в сводку.
  • Пропуски в агрегатах. Без na.rm = TRUE группа с NA вернёт NA.

Итог

  • group_by(col) делит таблицу на группы по значениям колонки.
  • summarise считает по одной сводной строке на группу.
  • n() — число строк, mean/sum/median — числовые сводки.
  • Это код-аналог сводных таблиц Excel, воспроизводимый и читаемый.
Проверьте себя
1. Что делает group_by сам по себе?
AСчитает среднее
BПомечает таблицу, разбивая её на группы для последующей агрегации
CУдаляет дубликаты
DСортирует строки
2. Чем summarise отличается от mutate?
AНичем
Bsummarise схлопывает строки в сводку, mutate сохраняет все строки
Cmutate считает по группам, summarise — нет
Dsummarise сортирует данные
3. Какая функция возвращает число строк в группе?
Acount()
Bn()
Clength()
Dsize()