Как читать ящик с усами
Ящик с усами сжимает целое распределение до пяти чисел и рисует их одним компактным знаком. Научиться его читать — дело тридцати секунд, так что начнём с этого; у каждой части есть точный смысл:
- Жирная линия внутри ящика — это медиана: половина данных лежит ниже неё, половина выше.
- Сам ящик охватывает межквартильный размах (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 даёт пять чисел, стоящих за ящиком: концы усов, границы ящика и медиану.