Что показывает гистограмма
Гистограмма отвечает на один вопрос об одной числовой переменной: как распределены значения? Она нарезает диапазон данных на последовательные интервалы, считает, сколько наблюдений попало в каждый, и рисует по столбцу на интервал высотой в это количество. Там, где данные плотные, столбцы высокие; где разрежённые — низкие.
Одна эта картинка сообщает то, чего не расскажут среднее и стандартное отклонение: один у данных пик или два, симметричны они или скошены в один хвост и есть ли отдельные значения далеко от остальных. Обычно это самый первый график при знакомстве с новым набором данных, рядом с числами из описательных статистик.
В R за это отвечает функция hist(), и это одна строка.
Ваша первая гистограмма через hist()
Смоделируем рост 200 человек — нормально распределённый вокруг 170 см со стандартным отклонением 10 (о том, что делают set.seed() и rnorm(), см. случайные числа):
set.seed(42)
heights <- rnorm(200, mean = 170, sd = 10)
hist(heights)
R сам подбирает интервалы и рисует колоколообразную стопку столбцов: низкие столбцы около 145 см, растущие к диапазону 160-х, пик около 170 и симметричный спад после 190. Вертикальная ось подписана «Frequency» — сырые количества, — а заголовок и подпись оси берутся из имени переменной.
Умолчания намеренно скромны. Обычные аргументы для приукрашивания работают и здесь:
hist(heights,
main = "Distribution of heights",
xlab = "Height (cm)",
col = "steelblue",
border = "white")
col заливает столбцы, border красит их контуры — border = "white" даёт чистый вид с разделёнными столбцами, который вы видите в большинстве публикаций. Всё, что руководство по plot() говорит о цветах и заголовках, применимо без изменений.
Ширина интервала: аргумент breaks
Самый важный аргумент hist() — это breaks, потому что ширина интервала решает, какую историю расскажет график. Те же данные, две настройки:
hist(heights, breaks = 5) # five wide bins: a crude, blocky bell
hist(heights, breaks = 30) # thirty narrow bins: detail, plus noise
При breaks = 5 гистограмма настолько груба, что всё выглядит гладким одиночным горбом — второй кластер или провал в данных были бы невидимы. При breaks = 30 вы видите тонкую структуру, но случайные колебания начинают выдавать себя за особенности. Ни то ни другое не «правильно»; честный ход — попробовать несколько настроек и посмотреть, какие особенности выживут.
breaks принимает три формы:
- Число —
breaks = 30— пожелание относительно количества интервалов. R подгоняет его к аккуратным границам, так что вы можете получить 28 или 33 интервала. Это всех однажды удивляет. - Вектор точек разреза —
breaks = seq(140, 200, by = 5)— точные границы интервалов, без переговоров. Используйте это, когда интервалы должны совпадать на нескольких сравниваемых гистограммах. - Название правила —
breaks = "FD"для Фридмана — Диакониса, которое выбирает ширину по разбросу данных и размеру выборки и хорошо ведёт себя на скошенных данных.
Гистограммы плотности и нормальная кривая
По умолчанию высоты столбцов — это количества (freq = TRUE). Установка freq = FALSE перемасштабирует столбцы так, чтобы их суммарная площадь равнялась 1, — это шкала плотности. Форма не меняется, меняется вертикальная ось. Смысл в том, что гистограмма плотности живёт на той же шкале, что и функция плотности вероятности, поэтому теоретическую кривую можно наложить прямо поверх данных:
hist(heights,
freq = FALSE,
col = "gray90",
main = "Heights vs. a normal curve",
xlab = "Height (cm)")
curve(dnorm(x, mean = mean(heights), sd = sd(heights)),
add = TRUE, col = "tomato", lwd = 2)
curve() с add = TRUE рисует колоколообразную кривую поверх существующей гистограммы (x внутри dnorm(x, ...) — это подстановка, которую заполняет сама curve(), а не ваша переменная). Если столбцы льнут к кривой, нормальная модель разумна; там, где они выпирают от неё — тяжёлый хвост, второй пик, — модель чего-то не улавливает. Пропустите freq = FALSE — и кривая бесполезно поползёт по низу графика, потому что количества и плотности находятся на разных шкалах.
Числа за столбцами
hist() не только рисует — она возвращает разбиение списком. С plot = FALSE она вообще пропускает рисование и только считает, а значит, вот это можно запустить прямо здесь:
h$counts — это гистограмма в виде данных: каждое число является высотой одного столбца. Строка table(cut(...)) — текстовый эквивалент: cut() разбивает значения на интервалы, table() их считает, — и это неплохая проверка здравого смысла, которую можно напечатать перед графиком или вместо него. Если присвоить без plot = FALSE (h <- hist(heights)), R и нарисует, и вернёт список; присваивание не подавляет график.
Гистограммы в ggplot2
Версия на ggplot2 меняет breaks на binwidth, что часто оказывается более естественным регулятором: вы говорите, насколько широк интервал в единицах данных, вместо того чтобы указывать их количество:
library(ggplot2)
ggplot(data.frame(heights), aes(x = heights)) +
geom_histogram(binwidth = 5, fill = "steelblue", color = "white") +
labs(title = "Distribution of heights", x = "Height (cm)", y = "Count")
binwidth = 5 означает, что каждый столбец покрывает 5 см. ggplot2 предупреждает вас, если оставить binwidth незаданным, и тихо использует 30 интервалов — прислушайтесь к предупреждению, потому что умолчание редко оказывается верной шириной для ваших данных. Для быстрого взгляда на одну переменную hist() требует меньше набора; ggplot2 окупается, когда гистограмме нужны фасеты, группы или общий стиль с остальными вашими рисунками.
Что вы уносите с собой
- Гистограмма показывает распределение одной числовой переменной:
hist(x)— и готово. breaks— тот самый важный аргумент: число это лишь пожелание, вектор задаёт точные границы,"FD"выбирает обоснованную ширину. Всегда пробуйте больше одной настройки.freq = FALSEпереключает на шкалу плотности, и именно это позволяетcurve(dnorm(...), add = TRUE)осмысленно наложить нормальную кривую.hist(x, plot = FALSE)возвращает интервалы данными ($breaks,$counts,$mids);table(cut(x, breaks))— чисто текстовый эквивалент.- В ggplot2 это
geom_histogram(binwidth = ...)— и задавайтеbinwidthсами.
Дальше: ящик с усами — график распределения, который по-настоящему блистает при сравнении групп бок о бок.
Часто задаваемые вопросы
Как построить гистограмму в R?
Вызовите hist(x) на числовом векторе. R разобьёт диапазон x на интервалы и нарисует по столбцу на интервал, где высота столбца показывает, сколько значений попало внутрь. Добавьте breaks =, чтобы управлять числом интервалов, и col =, чтобы раскрасить столбцы.
Что делает аргумент breaks в hist()?
Он управляет разбиением на интервалы. Одиночное число вроде breaks = 30 — это пожелание относительно числа интервалов (R округляет до аккуратных границ), вектор вроде breaks = seq(140, 200, by = 5) задаёт точные точки разреза, а breaks = "FD" использует правило Фридмана — Диакониса.
Как наложить нормальную кривую на гистограмму в R?
Постройте гистограмму на шкале плотности через freq = FALSE, а затем добавьте кривую через curve(dnorm(x, mean = mean(data), sd = sd(data)), add = TRUE). На частотной шкале кривая бесполезно легла бы у нуля, поэтому freq = FALSE обязателен.
В чём разница между гистограммой и столбчатой диаграммой?
Гистограмма разбивает на интервалы одну числовую переменную, поэтому горизонтальная ось непрерывна, а столбцы соприкасаются. Столбчатая диаграмма сравнивает различные категории, поэтому столбцы разделены. В R это hist() для чисел и barplot() для количеств по категориям.