Menu

Гистограмма в R: функция hist() с примерами

Как построить гистограмму в R с помощью hist() — выбор интервалов, оформление столбцов, переход на шкалу плотности, наложение нормальной кривой и версия на ggplot2.

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

Что показывает гистограмма

Гистограмма отвечает на один вопрос об одной числовой переменной: как распределены значения? Она нарезает диапазон данных на последовательные интервалы, считает, сколько наблюдений попало в каждый, и рисует по столбцу на интервал высотой в это количество. Там, где данные плотные, столбцы высокие; где разрежённые — низкие.

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

В 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() для количеств по категориям.

Coddy programming languages illustration

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

НАЧАТЬ