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

如何在R语言中为分布分位数添加geom_vline()垂直线?

问题描述

我绘制了如下密度图:
按年份分面的RWAGE密度图

我希望为每个按YEAR划分的分面,添加对应分布25%、50%、75%分位数的垂直线。我知道可以手动计算各年份的统计汇总值来实现,但想了解更高效的方法。

我的代码如下:

merge(usa_census_sub, CPI, by.x = "YEAR", by.y = "year")%>%
  select(YEAR, INCWAGE, rate)%>%
  filter(YEAR >= 1960 & INCWAGE !=999999 & INCWAGE !=0)%>%
  mutate(log_INCWAGE <- (log10(INCWAGE)),
         RWAGE = (log_INCWAGE/rate)*158)%>%
  ggplot(usa_census_sub, mapping = aes(x= RWAGE))+
  geom_density()+
  facet_wrap(~YEAR)
高效解决方案

方法1:用stat_summary直接生成垂直线

无需提前计算分位数,直接借助ggplot的stat_summary函数,在每个分面自动计算并绘制对应分位数的垂直线:

merge(usa_census_sub, CPI, by.x = "YEAR", by.y = "year")%>%
  select(YEAR, INCWAGE, rate)%>%
  filter(YEAR >= 1960 & INCWAGE !=999999 & INCWAGE !=0)%>%
  mutate(log_INCWAGE = log10(INCWAGE),  # 修正mutate内的赋值符号为=
         RWAGE = (log_INCWAGE/rate)*158)%>%
  ggplot(mapping = aes(x= RWAGE))+  # 移除多余的data参数,管道已传递处理后的数据
  geom_density()+
  # 添加分位数垂直线
  stat_summary(
    geom = "vline",
    fun.data = function(x) data.frame(xintercept = quantile(x, c(0.25, 0.5, 0.75))),
    color = c("blue", "red", "blue"),  # 中位数用红色,上下四分位数用蓝色区分
    linetype = c("dashed", "solid", "dashed")
  )+
  facet_wrap(~YEAR)

方法2:预处理分位数数据(更灵活)

如果需要对分位数做更多自定义操作,比如添加图例、调整样式,可以先通过分组计算得到分位数数据集,再用geom_vline调用:

# 预处理:计算各年份的分位数
quantile_data <- merge(usa_census_sub, CPI, by.x = "YEAR", by.y = "year")%>%
  select(YEAR, INCWAGE, rate)%>%
  filter(YEAR >= 1960 & INCWAGE !=999999 & INCWAGE !=0)%>%
  mutate(log_INCWAGE = log10(INCWAGE),
         RWAGE = (log_INCWAGE/rate)*158)%>%
  group_by(YEAR)%>%
  summarize(
    q25 = quantile(RWAGE, 0.25),
    q50 = quantile(RWAGE, 0.5),
    q75 = quantile(RWAGE, 0.75)
  )%>%
  tidyr::pivot_longer(cols = c(q25, q50, q75), names_to = "quantile", values_to = "value")

# 绘制图形
merge(usa_census_sub, CPI, by.x = "YEAR", by.y = "year")%>%
  select(YEAR, INCWAGE, rate)%>%
  filter(YEAR >= 1960 & INCWAGE !=999999 & INCWAGE !=0)%>%
  mutate(log_INCWAGE = log10(INCWAGE),
         RWAGE = (log_INCWAGE/rate)*158)%>%
  ggplot(mapping = aes(x= RWAGE))+
  geom_density()+
  geom_vline(data = quantile_data, aes(xintercept = value, color = quantile, linetype = quantile))+
  scale_color_manual(values = c("q25" = "blue", "q50" = "red", "q75" = "blue"))+
  scale_linetype_manual(values = c("q25" = "dashed", "q50" = "solid", "q75" = "dashed"))+
  facet_wrap(~YEAR)

注意事项

  • 原代码中mutate内使用<-赋值是错误的,需改为=;
  • ggplot无需重复传入usa_census_sub作为data参数,管道已将处理后的数据传递给ggplot;
  • 两种方法都会自动按分面的YEAR匹配对应分位数,无需手动逐个年份处理。

内容的提问来源于stack exchange,提问作者Nea

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 18:45:22