Skip to content

R - 直方图

直方图是一种重要的可视化工具,用于显示连续变量的分布。它将值分组成范围(或“bins”),并以条形图的形式显示每个 bin 中观测值的频率。

虽然 R 的基本图形包含 hist() 函数用于快速绘图,但创建灵活、出版质量图形的现代标准是 ggplot2 包,它是 tidyverse 的核心部分。ggplot2 基于“图形语法”(Grammar of Graphics),这是一个逐层构建图表的系统。

在 ggplot2 中创建直方图的基本语法是:

# 首先,确保已安装并加载 ggplot2
# install.packages("ggplot2")
library(ggplot2)
ggplot(data = <YOUR_DATA_FRAME>, aes(x = <VARIABLE_TO_PLOT>)) +
geom_histogram()

关键组成部分:

  • ggplot():初始化图表。您在此处指定数据集。
  • aes():美学映射。您将数据中的变量映射到图表的视觉属性,例如 x 轴、y 轴、颜色、填充等。
  • geom_histogram():几何对象,它告诉 ggplot2 绘制直方图。这通过 + 添加。
  • +:图层运算符。您使用它向图表添加更多元素,例如几何对象、标签、主题等。

让我们使用 R 内置的 cars 数据集中的 speed 变量创建一个直方图。cars 数据集是一个数据帧,这是 ggplot2 的标准输入格式。

# 加载库
library(ggplot2)
# 创建直方图
# 我们指定数据集 'cars' 并将 'speed' 列映射到 x 轴。
hist_plot <- ggplot(data = cars, aes(x = speed)) +
geom_histogram(
binwidth = 5, # 控制每个 bin 的宽度
fill = "steelblue", # 设置条形的填充颜色
color = "white" # 设置条形的边框颜色
) +
labs( # 添加标签
title = "Distribution of Car Speeds",
x = "Speed (mph)",
y = "Frequency (Count)",
caption = "Data source: R's built-in 'cars' dataset"
) +
theme_minimal() # 应用简洁的最小主题
# 显示图表
print(hist_plot)
# 将图表保存到文件
# ggsave() 是保存图表的现代方式。
# 它会自动从扩展名中检测格式。
ggsave("car_speed_histogram.png", plot = hist_plot, width = 6, height = 4)

执行上述代码会生成一个直方图。x 轴显示以 5 英里/小时为间隔分组的汽车速度。y 轴显示落入每个速度分组的汽车数量。条形为钢蓝色,带有白色边框,图表具有清晰的标题和轴标签。ggsave() 命令将在您的工作目录中创建一个名为 car_speed_histogram.png 的文件。

ggplot2 的强大之处在于其可定制性。您可以轻松修改美学、刻度和坐标。

让我们使用 mpg 数据集创建一个更复杂的图表。我们将查看每加仑高速公路英里数(hwy)的分布,并按汽车的类别(class)分割视图。

# 如果尚未加载 ggplot2,请加载它
library(ggplot2)
# 创建分面直方图
facet_plot <- ggplot(data = mpg, aes(x = hwy)) +
geom_histogram(binwidth = 2, fill = "#4C72B0", color = "white") +
# facet_wrap 为 'class' 中的每个类别创建单独的图表
facet_wrap(~ class, nrow = 2) +
# coord_cartesian 是在不删除数据的情况下进行缩放的最佳方式
coord_cartesian(xlim = c(10, 50)) +
labs(
title = "Highway MPG Distribution by Vehicle Class",
x = "Highway Miles Per Gallon (MPG)",
y = "Count"
) +
theme_light()
print(facet_plot)

此代码生成一个小型直方图网格,每个车辆类别(例如,“suv”、“compact”、“pickup”)一个。这使得比较不同类别之间的 MPG 分布变得非常容易。所有图表共享相同的 x 轴和 y 轴,以便进行一致的比较。

  • 尝试 binwidth:bin 的数量可以显著改变直方图的解释。尝试几个值以找到最能揭示底层数据结构的值。
  • 使用 facet_wrap() 进行比较:当您想比较不同组之间的分布时,分面比尝试叠加多个直方图更有效。
  • 标记所有内容:始终提供描述性标题、轴标签和来源说明。labs() 可以轻松实现这一点。
  • 考虑可访问性:使用对色盲人士友好的调色板。像 viridis 这样的包提供了出色的选项。