R语言格式化鲸鱼观测数据并绘制按母系分组的计数热图
R语言鲸鱼观测热图实现方案
核心问题修复点说明
现有代码存在4个核心问题,对应修复逻辑如下:
- 排序异常:默认字符串排序会将
L12排在L2之前(逐字符比较时"1"<"2"),需拆分编号中的字母前缀与数字部分,按数值大小排序 - 刻度小数:
scale_fill_gradient默认自动计算刻度断点,会生成非整数刻度,需手动指定整数断点 - 排版错位:分面未设置自由y轴,导致不同母系分面高度一致、鲸鱼ID顺序错乱,需配置自由轴与匹配空间
- 笔误修正:代码中
matr为字段名笔误,原始数据对应字段为matriline
1. 数据格式化处理代码
首先加载依赖包,完成长表转热图所需格式的处理,同时生成排序用的辅助列:
library(tidyverse) # 数据预处理 socialmap <- id %>% # 拆分母系、ID的字母前缀与数字编号,用于数值排序 mutate( # 拆分母系编号 matri_prefix = str_extract(matriline, "^[A-Z]+"), matri_num = as.numeric(str_extract(matriline, "\\d+")), # 拆分鲸鱼ID编号 id_prefix = str_extract(id, "^[A-Z]+"), id_num = as.numeric(str_extract(id, "\\d+")), # 生成时间分组列 x = case_when( year < 1960 ~ "Pre-1960", year %in% 1960:1969 ~ "1960-1969", year %in% 1970:1979 ~ "1970-1979", year %in% 1980:1989 ~ "1980-1989", year %in% 1990:1999 ~ "1990-1999", TRUE ~ as.character(year) ), # 生成y轴鲸鱼ID标识 y_label = as.character(id) ) %>% # 按时间+鲸鱼ID分组计数 group_by(matriline, matri_num, y_label, id_num, x, .drop = FALSE) %>% summarize(count = n(), .groups = "drop") %>% # 补全所有缺失的时间-鲸鱼组合,未观测计数填0 complete(x, nesting(matriline, matri_num, y_label, id_num), fill = list(count = 0)) %>% # 设置因子水平,固定排序规则 mutate( # x轴时间顺序 x = factor(x, levels = c("Pre-1960", "1960-1969", "1970-1979", "1980-1989", "1990-1999", as.character(2000:2020))), # 母系按数字顺序排序 matriline = fct_reorder(matriline, matri_num), # 同母系下鲸鱼ID按数字顺序排序 y_label = fct_reorder(y_label, id_num, .by = matriline) )
处理后的数据完全符合绘图要求:每一行对应单个鲸鱼-单个时间单元的观测计数,所有排序规则已通过因子水平固定。
2. 热图绘制代码
绘图时修复刻度、排版问题,完全匹配需求规则:
ggplot(socialmap, aes(x = x, y = y_label, fill = count)) + geom_tile(color = "white", linewidth = 0.2) + # 添加白色单元格边框提升可读性 # 填充色阶设置:手动指定整数刻度,解决小数显示问题 scale_fill_gradient( low = "#deebf7", high = "#de2d26", # 蓝到红渐变,视觉效果更柔和 breaks = 0:5, # 匹配0-5的计数范围,全整数刻度 labels = 0:5, name = "观测次数" ) + # x轴放置在顶部 scale_x_discrete(position = "top") + # 按母系分面,配置自由y轴 facet_grid( rows = vars(matriline), strip.position = "left", scales = "free_y", space = "free_y" # 分面高度和所含鲸鱼数量自动匹配 ) + labs(x = NULL, y = NULL) + theme_minimal() + theme( panel.spacing = unit(0, "lines"), strip.background = element_blank(), strip.placement = "outside", axis.text.x = element_text(angle = 45, hjust = 0), # 年份标签倾斜避免重叠 strip.text.y.left = element_text(angle = 0, hjust = 1) # 母系标签横向显示 )
效果说明
- 横轴自动按「年代分组+2000年后单自然年」顺序排列
- 纵轴鲸鱼严格按母系数字顺序、同母系ID数字顺序分组排列
- 单元格颜色深度和观测次数正相关,色阶刻度全为整数
- 不同母系分面无多余空白,排版紧凑
内容的提问来源于stack exchange,提问作者burphound
相关产品推荐
相关产品推荐

