如何在R语言中为分布分位数添加geom_vline()垂直线?
问题描述
我绘制了如下密度图:
我希望为每个按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
相关产品推荐
相关产品推荐

