You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.19 21:15:36