如何让geom_freqpoly()中各曲线值的总和在任意点均为1?
实现频率多边形各分组在任意x值处比例和为1
你提到的after_stat(ncount)是将每个分组自身的频率归一到0-1区间,但如果要让任意hp值对应的所有cyl分组比例之和为1,需要基于全局的区间计数来计算比例,而不是分组内的归一。下面提供两种可行的方法:
方法一:手动预处理数据(直观可控)
先对hp分箱,统计每个cyl分组在每个区间的数量,再计算该区间内各分组的占比,最后绘制折线:
library(tidyverse) # 数据预处理:分箱、统计计数、计算比例 mtcars_summary <- mtcars %>% mutate(cyl = as.factor(cyl)) %>% # 按照geom_freqpoly的bins=5对hp分箱 mutate(hp_bin = cut(hp, bins = 5)) %>% count(cyl, hp_bin) %>% # 按hp区间分组,计算每个区间的总计数,再算占比 group_by(hp_bin) %>% mutate(prop = n / sum(n)) %>% ungroup() %>% # 提取每个区间的中点作为x轴的连续值,让折线更自然 mutate(hp_mid = map_dbl(hp_bin, ~mean(as.numeric(.x)))) # 绘制比例折线图 ggplot(mtcars_summary, aes(x = hp_mid, y = prop, color = cyl)) + geom_line(linewidth = 1) + labs(x = "马力(hp)", y = "区间内占比", color = "气缸数(cyl)")
方法二:直接在ggplot中用stat函数计算
可以利用stat_bin结合after_stat直接计算全局区间的比例,无需提前预处理数据:
library(tidyverse) mtcars %>% mutate(cyl = as.factor(cyl)) %>% ggplot(aes(x = hp, color = cyl)) + stat_bin( # 计算当前区间内分组计数占该区间总计数的比例 aes(y = after_stat(count / tapply(count, after_stat(x), sum)[as.character(after_stat(x))])), bins = 5, geom = "line" ) + labs(x = "马力(hp)", y = "区间内占比", color = "气缸数(cyl)")
两种方法都能实现任意hp区间内,所有cyl分组的比例之和为1的效果,第一种方法更便于查看中间计算结果,第二种则更简洁。
内容的提问来源于stack exchange,提问作者max
相关产品推荐
相关产品推荐

