R语言计算分箱数据中tag类别的相对占比并绘制堆叠条形图
分箱内tag相对占比计算与堆叠图实现
核心实现逻辑
计算的核心要满足两个规则:
- 每个分箱内部独立计算占比,占比分母为当前分箱的总观测数
- 必须覆盖所有tag类别,分箱内不存在的tag占比记为0,不能遗漏
对照示例规则验证:10-20分箱共包含3条观测(b/c/d各1条,无a类tag),对应占比为a=0,b/c/d各约33.3%,和规则完全匹配。
代码实现
1. 基于tidyverse的计算版本
这是最常用的简洁实现,需要先安装加载对应包:
library(dplyr) library(tidyr) library(ggplot2) # 获取所有存在的tag类别 all_tags <- unique(df$tag) # 计算分箱内tag统计量 bin_tag_stats <- df %>% # 按分箱、tag维度计数 count(bin, tag, name = "cnt") %>% # 补全所有分箱和tag的组合,缺失值计数填0 complete(bin, tag, fill = list(cnt = 0)) %>% # 计算当前分箱内的相对百分比 group_by(bin) %>% mutate(ratio = cnt / sum(cnt) * 100) %>% ungroup()
运行后查看10-20分箱的统计结果,和预期验证值完全一致。
2. 基础R无依赖版本
不需要加载第三方包也可实现相同结果:
# 生成所有分箱与tag的全组合 combo <- expand.grid(bin = levels(df$bin), tag = unique(df$tag)) # 统计每个组合对应的观测数量 combo$cnt <- mapply(function(b, t) sum(df$bin == b & df$tag == t), combo$bin, combo$tag) # 统计每个分箱的总观测数 bin_total <- as.data.frame(table(df$bin)) names(bin_total) <- c("bin", "total") # 合并计算占比 bin_tag_stats <- merge(combo, bin_total, by = "bin") bin_tag_stats$ratio <- bin_tag_stats$cnt / bin_tag_stats$total * 100
堆叠条形图绘制
基于计算完成的统计结果,直接调用ggplot2绘制堆叠百分比条形图:
ggplot(bin_tag_stats, aes(x = bin, y = ratio, fill = tag)) + geom_col(position = "stack", color = "white") + # 在堆叠块中心添加占比标签 geom_text(aes(label = paste0(round(ratio, 1), "%")), position = position_stack(vjust = 0.5), size = 3) + labs(x = "value值分箱", y = "分箱内tag占比(%)", fill = "tag类别") + theme_bw()
常见注意点
- 直接使用基础交叉表计算占比时,容易遗漏分箱下不存在的tag类别,导致分箱内占比总和不对,必须先补全所有分箱与tag的组合再开展计算
- 当前使用的
cut()函数默认左开右闭规则,会将边界值(比如value=20、value=40)归入右侧区间,和示例验证的分箱划分逻辑完全匹配,不需要额外调整参数
内容的提问来源于stack exchange,提问作者Sphinx
相关产品推荐
相关产品推荐

