Menu

Ящик с усами в R: boxplot() по группам с примерами

Как построить ящик с усами в R через boxplot() — чтение ящика и усов, формульный интерфейс для сравнения групп, оформление и числа, стоящие за графиком.

На этой странице есть исполняемые редакторы: меняйте, запускайте и сразу видите результат.

Как читать ящик с усами

Ящик с усами сжимает целое распределение до пяти чисел и рисует их одним компактным знаком. Научиться его читать — дело тридцати секунд, так что начнём с этого; у каждой части есть точный смысл:

  • Жирная линия внутри ящика — это медиана: половина данных лежит ниже неё, половина выше.
  • Сам ящик охватывает межквартильный размах (IQR) — от первого квартиля (25% данных ниже) до третьего квартиля (75% ниже). Внутри ящика живёт средняя половина ваших данных.
  • Усы — это линии, отходящие от ящика. Каждый дотягивается до самой крайней точки данных, всё ещё находящейся в пределах 1.5 × IQR от края ящика, так что они покрывают «обычный диапазон» данных, а не весь размах.
  • Отдельные точки за усами — значения, отстоящие от ящика более чем на 1.5 × IQR: помечены как подозреваемые выбросы и нарисованы поштучно, чтобы их можно было пересчитать.

Высокий ящик означает разбросанные данные; линия медианы, смещённая от центра ящика, означает скошенность; шлейф точек за одним из усов означает тяжёлый хвост с этой стороны. Гистограмма показывает то же распределение подробнее, но суперсила ящика с усами в том, что десяток таких умещается бок о бок, а это делает его тем самым графиком для сравнения групп.

Ящик с усами для одной переменной

Функция называется boxplot(), и для одного числового вектора это один вызов:

scores <- c(52, 55, 58, 60, 61, 63, 64, 66, 68, 70, 72, 95)

boxplot(scores,
        main = "Test scores",
        ylab = "Score")

Вот что рисуется: ящик от 59 до 69 с линией медианы на 63.5, усы, дотягивающиеся вниз до 52 и вверх до 72, и одна одинокая точка, парящая на 95, — выброс, который сводка из среднего и стандартного отклонения тихо поглотила бы. Это мгновенное «одно значение не похоже на остальные» и есть смысл ящиков с усами.

(Как и на каждой странице этой главы, вызовы построения графиков приведены статичными сниппетами — исполнитель ниже показывает только текстовый вывод. Запускайте их локально, чтобы увидеть рисунок.)

Сравнение групп: формульный интерфейс

Настоящее повседневное применение — по ящику на группу, и для этого boxplot() принимает формулу: y ~ group, читается как «y в разбивке по группе». Встроенный набор данных R ToothGrowth — длина зубов у 60 морских свинок, получавших витамин C через апельсиновый сок (OJ) или аскорбиновую кислоту (VC), — классическая демонстрация:

boxplot(len ~ supp,
        data = ToothGrowth,
        main = "Tooth growth by supplement",
        xlab = "Supplement",
        ylab = "Tooth length")

Появляются два ящика на общей вертикальной шкале: ящик OJ заметно выше ящика VC, с медианой около 22 против примерно 19. Поскольку оба ящика делят одну ось, сравнение честно по построению — исключён вариант с двумя графиками в разных масштабах, льстящими одной из групп. Группирующий столбец должен быть фактором (или символьным вектором); каждый уровень становится одним ящиком.

Формулы также вкладываются: boxplot(len ~ supp * dose, data = ToothGrowth) рисует шесть ящиков, по одному на комбинацию добавки и дозы. Когда различие групп на ящиках выглядит настоящим, естественный следующий вопрос — больше ли это, чем шум, — и на него отвечает t-критерий.

Подписи, цвета и горизонтальные ящики

Аргументы оформления следуют соглашениям базовой графики. names подписывает ящики, col их заливает — передайте вектор, чтобы раскрасить каждую группу по-своему:

boxplot(len ~ supp,
        data  = ToothGrowth,
        names = c("Orange juice", "Ascorbic acid"),
        col   = c("orange", "lightblue"),
        main  = "Tooth growth by supplement",
        ylab  = "Tooth length")

Ещё два переключателя окупаются:

  • horizontal = TRUE поворачивает весь график так, что ящики идут вдоль горизонтальной оси. Делайте так всякий раз, когда названия групп длинные: горизонтальные подписи остаются читаемыми там, где вертикальные сталкиваются.
  • notch = TRUE вырезает выемку вокруг каждой медианы; когда выемки двух групп не перекрываются, их медианы правдоподобно различаются. Относитесь к этому как к визуальной подсказке, а не как к критерию.

Числа за ящиком

Всё, что рисует график, происходит из чисел, которые можно напечатать. quantile() даёт пятичисловую сводку, а boxplot.stats() даёт ровно то, что использует график, включая выбросы. Вот это можно запустить прямо здесь:

Обратите внимание, что эти двое — родственники, а не близнецы: quantile() сообщает истинные минимум и максимум, а s$stats заканчивается на усах — самых крайних точках внутри ограды 1.5 × IQR. Разрыв между ними и есть s$out, здесь одинокая 95. Когда кто-то спрашивает «что это за точки-выбросы?», ответ даёт x[x %in% boxplot.stats(x)$out] — или фильтр по значениям ограды.

Ящики с усами в ggplot2

В ggplot2 группировка уходит в отображение эстетик вместо формулы:

library(ggplot2)

ggplot(ToothGrowth, aes(x = supp, y = len, fill = supp)) +
    geom_boxplot() +
    labs(title = "Tooth growth by supplement",
         x = "Supplement", y = "Tooth length")

Те же два ящика, с легендой и темой в подарок. Версия ggplot2 лучше масштабируется, когда график разрастается: разбейте на фасеты по dose, наложите сырые точки через geom_jitter(width = 0.1) — и код останется декларативным. Для разового сравнения по ходу анализа boxplot(y ~ g, data = df) остаётся самым быстрым, что можно набрать.

Что вы уносите с собой

  • Анатомия ящика: линия медианы, ящик = IQR, усы = самые крайние точки в пределах 1.5 × IQR, точки за ними = подозреваемые выбросы.
  • boxplot(x) — для одной переменной; boxplot(y ~ group, data = df) — для сравнения групп бок о бок на одной честной общей шкале.
  • Оформляйте через names, вектор col по группам и horizontal = TRUE, когда подписи длинные.
  • boxplot.stats(x)$stats и $out — это график в числах; используйте их, чтобы извлечь выбросы, на которые указывает график.
  • ggplot2: geom_boxplot() с группой, отображённой на x или fill.

Дальше: диаграмма рассеяния — от распределения одной переменной к связи между двумя.

Часто задаваемые вопросы

Как построить ящик с усами в R?

Вызовите boxplot(x) на числовом векторе для одного ящика или используйте формульный интерфейс boxplot(y ~ group, data = df), чтобы получить по ящику на группу рядом друг с другом. Обе формы поставляются с базовым R — пакеты не нужны.

Что означают части ящика с усами?

Жирная линия внутри ящика — медиана. Ящик охватывает межквартильный размах, от первого квартиля до третьего. Усы дотягиваются до самых крайних точек данных в пределах 1.5 межквартильных размахов от ящика, а всё, что за усами, рисуется отдельными точками — как подозреваемые выбросы.

Как построить ящик с усами по группам в R?

Используйте формулу: boxplot(len ~ supp, data = ToothGrowth) рисует по ящику на каждый уровень supp. Группирующая переменная должна быть фактором или символьным столбцом; каждый уровень становится одним ящиком на общей шкале.

Как найти выбросы, которые показывает ящик с усами?

boxplot.stats(x)$out возвращает ровно те значения, которые график нарисовал бы точками за усами, а boxplot.stats(x)$stats даёт пять чисел, стоящих за ящиком: концы усов, границы ящика и медиану.

Coddy programming languages illustration

Учитесь программировать с Coddy

НАЧАТЬ