如何在R中按学校层级制作展示袭击事件数的直方图?
问题与解决方案
我有一个包含三列的数据集:学校名称、学校层级(小学elementary、中学middle、高中high school)、各学校袭击事件数量。想用R制作直方图,原代码如下:
hist_math2 <- ggplot(data=philadelphia.schools$SCHOOL_LEVEL_NAME, aes(x=Assaults)) + geom_histogram(binwidth=1, color="black", fill = "blue") + xlim(0,80) + ylim(0,35) + xlab("number of schools") + ylab("Assaults") facet_wrap(~ SCHOOL_LEVEL_NAME) hist_math2
运行后生成的图表不符合预期,希望将横轴从“number of schools”调整为更合理的设置(关联学校层级),并优化图表布局。
数据集示例:
| School_Name | School_Level | Assaults |
|---|---|---|
| JFK High Sch | High School | 45 |
| JFK Middle Sc | Middle School | 22 |
更新后的数据集dput:
structure(list(SCHOOL_LEVEL_NAME = c("HIGH SCHOOL", "HIGH SCHOOL", "HIGH SCHOOL", "HIGH SCHOOL", "HIGH SCHOOL", "MIDDLE SCHOOL", "HIGH SCHOOL", "ELEMENTARY SCHOOL", "ELEMENTARY SCHOOL", "ELEMENTARY SCHOOL", "ELEMENTARY SCHOOL", "ELEMENTARY SCHOOL", "ELEMENTARY SCHOOL", "ELEMENTARY SCHOOL", "ELEMENTARY SCHOOL", "ELEMENTARY SCHOOL", "ELEMENTARY SCHOOL", "ELEMENTARY SCHOOL", "ELEMENTARY SCHOOL", "ELEMENTARY SCHOOL", "ELEMENTARY SCHOOL", "ELEMENTARY SCHOOL", "ELEMENTARY SCHOOL", "ELEMENTARY SCHOOL", "ELEMENTARY SCHOOL", "ELEMENTARY SCHOOL", "ELEMENTARY SCHOOL", "ELEMENTARY SCHOOL", "MIDDLE SCHOOL", "HIGH SCHOOL"), Assaults = c(31L, 25L, 14L, 4L, 30L, 10L, 2L, 33L, 22L, 5L, 8L, 1L, 12L, 11L, 12L, 7L, 6L, 15L, 8L, 12L, 2L, 3L, 16L, 6L, 18L, 17L, 19L, 11L, 3L, 51L)), row.names = c(NA, 30L), class = "data.frame")
修正后的代码与解释
1. 基础修正版(分面直方图)
原代码存在三个关键错误:
data参数传入单列向量,应传入整个数据框philadelphia.schools- 坐标轴标签颠倒:直方图的
x为袭击数,y为对应数量的学校,需调整标签对应关系 facet_wrap未用+连接到ggplot对象,导致分面不生效
修正代码:
library(ggplot2) # 加载数据集 philadelphia.schools <- structure(list(SCHOOL_LEVEL_NAME = c("HIGH SCHOOL", "HIGH SCHOOL", "HIGH SCHOOL", "HIGH SCHOOL", "HIGH SCHOOL", "MIDDLE SCHOOL", "HIGH SCHOOL", "ELEMENTARY SCHOOL", "ELEMENTARY SCHOOL", "ELEMENTARY SCHOOL", "ELEMENTARY SCHOOL", "ELEMENTARY SCHOOL", "ELEMENTARY SCHOOL", "ELEMENTARY SCHOOL", "ELEMENTARY SCHOOL", "ELEMENTARY SCHOOL", "ELEMENTARY SCHOOL", "ELEMENTARY SCHOOL", "ELEMENTARY SCHOOL", "ELEMENTARY SCHOOL", "ELEMENTARY SCHOOL", "ELEMENTARY SCHOOL", "ELEMENTARY SCHOOL", "ELEMENTARY SCHOOL", "ELEMENTARY SCHOOL", "ELEMENTARY SCHOOL", "ELEMENTARY SCHOOL", "ELEMENTARY SCHOOL", "MIDDLE SCHOOL", "HIGH SCHOOL"), Assaults = c(31L, 25L, 14L, 4L, 30L, 10L, 2L, 33L, 22L, 5L, 8L, 1L, 12L, 11L, 12L, 7L, 6L, 15L, 8L, 12L, 2L, 3L, 16L, 6L, 18L, 17L, 19L, 11L, 3L, 51L)), row.names = c(NA, 30L), class = "data.frame") hist_math2 <- ggplot(data = philadelphia.schools, aes(x = Assaults)) + geom_histogram(binwidth = 5, color = "black", fill = "steelblue") + xlim(0, 80) + ylim(0, 10) + # 根据数据调整y轴范围,减少空白区域 xlab("袭击事件数量") + ylab("学校数量") + facet_wrap(~ SCHOOL_LEVEL_NAME, ncol = 1) + # 单列分面,便于纵向比较 theme_minimal() hist_math2
2. 分组直方图(横轴为学校层级)
如果要直接将横轴设为学校层级,展示每个层级的袭击数分布,可使用分组直方图:
ggplot(data = philadelphia.schools, aes(x = SCHOOL_LEVEL_NAME, y = Assaults, fill = SCHOOL_LEVEL_NAME)) + geom_histogram(stat = "identity", bins = 5, color = "black", position = "dodge") + xlab("学校层级") + ylab("袭击事件数量") + scale_fill_brewer(palette = "Set2") + theme_minimal() + theme(axis.text.x = element_text(angle = 45, hjust = 1)) # 旋转标签避免重叠
布局优化建议
- 分面排列:用
facet_wrap(~ SCHOOL_LEVEL_NAME, ncol = 1)垂直排列分面,便于对比不同层级的袭击数分布趋势 - 调整bin宽度:原
binwidth=1过细,会导致直方图零散,改为5更符合数据密度 - 坐标轴范围:根据实际数据调整
ylim,避免出现大量无效空白 - 主题与样式:使用
theme_minimal()或theme_bw()替代默认主题,提升图表可读性;添加标题ggtitle("不同层级学校袭击事件数量分布")强化信息 - 颜色优化:分组直方图可按层级设置填充色,用
scale_fill_brewer选择专业配色方案,提升区分度
内容的提问来源于stack exchange,提问作者hd3_
相关产品推荐
相关产品推荐

