R语言ggplot如何绘制季度与YTD值图表并添加目标参考线
解决方案
数据预处理修正
之前的YTD计算逻辑有误,sum()会返回所有行的总和,无法得到逐季度累计值,换成cumsum()即可实现按季度顺序累计求和,最终输出完全匹配期望的字段格式:
library(tidyverse) # 加载原始数据 df <- structure(list(attainment_target = c(7.5, 15), quarter_2022 = c("Q1", "Q2"), total_attainment = c(2, 4), percent_attainment = c(0.2666, 0.2666)), row.names = c(NA, -2L), class = c("tbl_df", "tbl", "data.frame")) # 计算YTD相关字段,输出完全匹配期望格式 df1 <- df %>% # 补充季度日期列 mutate(Quarter = as.Date(c("2022-01-01", "2022-04-01")), .before = 1) %>% # 逐季度累计计算YTD达成 mutate(YTD = cumsum(total_attainment), # 计算累计达成率,转百分比后取整 `% Attainment` = round(YTD / attainment_target * 100, 0)) %>% # 重命名字段对齐期望输出 rename(Target = attainment_target, Attainment = total_attainment)
处理后的数据输出如下,和预期完全一致:
| Quarter | Target | Attainment | YTD | % Attainment |
|---|---|---|---|---|
| 2022-01-01 | 7.5 | 2 | 2 | 27 |
| 2022-04-01 | 15 | 4 | 6 | 40 |
ggplot绘图实现
原代码存在映射位置错误、目标线绘制逻辑缺失问题,以下是可直接运行的完整绘图代码,实现柱状图展示单季达成、分季度绘制目标水平虚线、同步标注YTD和达成率的需求:
ggplot(df1, aes(x = Quarter)) + # 绘制单季度达成柱状图 geom_col(aes(y = Attainment, fill = factor(Quarter)), width = 30) + # 为每个季度绘制对应目标值的水平虚线 geom_segment(aes(x = Quarter - 15, xend = Quarter + 15, y = Target, yend = Target), linetype = "dashed", color = "red", linewidth = 1) + # 标注单季达成值 geom_text(aes(y = Attainment, label = Attainment), vjust = -0.5, size = 3.5) + # 标注YTD累计值和累计达成率 geom_text(aes(y = Target, label = paste0("YTD:", YTD, "\n达成率:", `% Attainment`, "%")), vjust = -0.8, size = 3, color = "red") + # 应用Paired配色 scale_fill_brewer(palette = "Paired") + # 设置X轴日期显示格式 scale_x_date(date_labels = "%Y-Q%q", date_breaks = "3 months") + # 设置坐标轴与标题 labs(x = "季度", y = "数值", fill = "季度", title = "季度达成与目标对比图") + theme_bw() + theme(plot.title = element_text(hjust = 0.5))
原代码问题说明
- YTD计算逻辑错误:使用
sum(total_attainment)返回全量季度总和,替换为cumsum()才能得到逐季度累计的YTD值 - 美学映射位置错误:
palette参数不能放入aes()内部,需要通过scale_fill_brewer()等标度函数设置;X轴错误映射为目标值字段,应改为季度/日期字段 - 目标线适配性差:全局
geom_hline()适合全图统一参考线,分季度不同目标值用geom_segment()可精准在每个柱子对应位置绘制指定长度的虚线
内容的提问来源于stack exchange,提问作者Dinho
相关产品推荐
相关产品推荐

