R中含大量类别变量的热力图优化绘制技术问询
R语言多类别变量热力图优化方案
问题背景
刚接触R语言,尝试用热力图对比职业(30+类别)与受伤类型(30+类别)两个分类变量时,因类别过多导致热力图及坐标轴杂乱,无法有效解读结果。
示例数据与原代码
示例数据:
# 职业变量(实际含30+类别) OCCUPATION <- c("Warehouse Bagger","Maintanence Man","Utility Man","Errand Boy") # 另有20+类别 # 受伤类型变量(实际含30+类别) NATURE_INJURY <- c("Cut","Sprain","Bruise","Burn","Damaged Lung") # 另有30+类别
原绘制代码:
library(dplyr) counting <- count(new_data4, OCCUPATION, NATURE_INJURY) ggplot(data = counting, mapping = aes(x = OCCUPATION, y = NATURE_INJURY)) + geom_tile(mapping = aes(fill = n))
优化方案
1. 合并低频类别
将计数占比极低的职业或受伤类型合并为「其他」类别,聚焦核心群体,直接减少类别数量:
# 保留计数前20的职业,其余归为"其他" top_occupations <- new_data4 %>% count(OCCUPATION) %>% arrange(desc(n)) %>% slice(1:20) %>% pull(OCCUPATION) # 保留计数前20的受伤类型,其余归为"其他" top_injuries <- new_data4 %>% count(NATURE_INJURY) %>% arrange(desc(n)) %>% slice(1:20) %>% pull(NATURE_INJURY) # 生成清洗后的数据 clean_data <- new_data4 %>% mutate( OCCUPATION = ifelse(OCCUPATION %in% top_occupations, OCCUPATION, "其他"), NATURE_INJURY = ifelse(NATURE_INJURY %in% top_injuries, NATURE_INJURY, "其他") ) # 重新统计并绘图 counting_clean <- count(clean_data, OCCUPATION, NATURE_INJURY) ggplot(counting_clean, aes(x = OCCUPATION, y = NATURE_INJURY)) + geom_tile(aes(fill = n))
2. 优化坐标轴布局
通过旋转标签、交换坐标轴避免重叠,提升静态图可读性:
# 旋转x轴标签,避免横向重叠 ggplot(counting, aes(x = OCCUPATION, y = NATURE_INJURY)) + geom_tile(aes(fill = n)) + theme(axis.text.x = element_text(angle = 90, vjust = 0.5, hjust = 1)) # 交换坐标轴(适合两类别数量差异较大的场景) ggplot(counting, aes(x = OCCUPATION, y = NATURE_INJURY)) + geom_tile(aes(fill = n)) + coord_flip()
3. 过滤低计数组合
只保留计数大于阈值的职业-受伤类型组合,去掉无意义的空白/极低计数单元格:
# 过滤计数≥5的组合(阈值可根据数据调整) counting_filtered <- counting %>% filter(n >= 5) ggplot(counting_filtered, aes(x = OCCUPATION, y = NATURE_INJURY)) + geom_tile(aes(fill = n)) + theme(axis.text.x = element_text(angle = 90, vjust = 0.5, hjust = 1))
4. 改用交互式热力图
借助plotly包生成交互式图,鼠标悬停可查看具体类别与计数,无需压缩坐标轴:
library(plotly) p <- ggplot(counting, aes(x = OCCUPATION, y = NATURE_INJURY, fill = n)) + geom_tile() + theme(axis.text.x = element_text(angle = 90, vjust = 0.5, hjust = 1)) # 转换为交互式热力图 ggplotly(p)
内容的提问来源于stack exchange,提问作者HU EW
相关产品推荐
相关产品推荐

