如何对ggplot的geom_bin2d()按x轴分组进行归一化处理?
实现按age分组的value相对分布热力图
要实现每个age区间内value的相对分布热力图,核心是对每个age分组内的value区间计数做归一化(计算占该age分组总样本的比例),消除不同age区间样本量差异带来的偏差。以下是两种可行方案:
方法一:手动预处理数据后绘制热力图
先对数据进行分箱、计数并计算相对比例,再用geom_tile绘制热力图,这种方式更灵活,便于自定义分箱规则:
# 加载所需包 library(ggplot2) library(dplyr) library(stringr) # 生成示例数据 set.seed(1e3) n <- 1e3 dt <- data.frame( age = 50*rbeta(n, 5, 1), value = 1000*rbeta(n, 1, 3) ) # 按默认30个分箱对age和value分组,计算每个箱的计数 dt_binned <- dt %>% mutate( age_bin = cut(age, breaks = 30, labels = FALSE), value_bin = cut(value, breaks = 30, labels = FALSE) ) %>% count(age_bin, value_bin) %>% # 按age分组计算每个value区间的相对比例 group_by(age_bin) %>% mutate(prop = n / sum(n)) %>% ungroup() # 提取分箱的区间起始值用于坐标轴标签 age_intervals <- cut(dt$age, breaks = 30) value_intervals <- cut(dt$value, breaks = 30) dt_binned <- dt_binned %>% left_join( data.frame( age_bin = seq_along(levels(age_intervals)), age_center = levels(age_intervals) %>% str_extract("(?<=\\()[0-9.]+(?=,)") %>% as.numeric() ), by = "age_bin" ) %>% left_join( data.frame( value_bin = seq_along(levels(value_intervals)), value_center = levels(value_intervals) %>% str_extract("(?<=\\()[0-9.]+(?=,)") %>% as.numeric() ), by = "value_bin" ) # 绘制热力图 ggplot(dt_binned, aes(x = age_center, y = value_center, fill = prop)) + geom_tile(color = "white", size = 0.1) + # 添加白色边框区分箱 scale_fill_viridis_c(name = "相对比例") + labs(x = "age", y = "value") + theme_minimal()
方法二:用stat_summary_2d直接在ggplot中计算比例
利用stat_summary_2d可以直接对每个x-y分箱应用自定义函数,无需手动预处理数据,代码更简洁:
library(ggplot2) # 生成示例数据 set.seed(1e3) n <- 1e3 dt <- data.frame( age = 50*rbeta(n, 5, 1), value = 1000*rbeta(n, 1, 3) ) # 绘制相对分布热力图 ggplot(dt, aes(x = age, y = value)) + stat_summary_2d( fun = function(y) { # 对当前age分组内的value进行分箱 y_bins <- cut(y, breaks = 30, labels = FALSE) # 计算每个value分箱的相对比例 bin_counts <- table(y_bins) bin_props <- bin_counts / sum(bin_counts) # 返回每个数据点对应的比例值 bin_props[as.character(y_bins)] %>% as.numeric() }, bins = 30 ) + scale_fill_viridis_c(name = "相对比例") + labs(x = "age", y = "value") + theme_minimal()
说明
两种方法最终都会生成每个age区间内value的相对分布热力图,每个age列的颜色代表该value区间占该age组总样本的比例,完全消除了不同age区间样本量的差异,能清晰对比各age组内value的分布模式。
内容的提问来源于stack exchange,提问作者yeahman269
相关产品推荐
相关产品推荐

