为哑铃图准备日期数据:多分组日期数据转换方案问询
适配多日期分组的哑铃图绘制方案
问题背景
处理数据集绘制哑铃图时,需适配以下几种日期分组场景:
- 单日期组:仅含1个日期,
h_sequ值均为1,起始/结束日期相同 - 双日期组:含明确起始/结束日期,以
h_sequ值1和2标识(如组12) - 三日期组:含3个日期,
h_sequ取值为1、2、3(如组33) - 特殊情况:组33存在重复的
h_sequ=1行,实际对应1个日期
数据集
# 原始数据 group h_sequ date <int> <int> <date> 1 1 1 2012-03-27 2 1 1 2012-03-27 3 10 1 2016-10-25 4 10 1 2016-10-25 5 12 1 2021-06-25 6 12 2 2022-05-18 7 31 1 2019-11-28 8 31 1 2019-11-28 9 31 2 2021-03-24 10 33 1 2013-09-03 11 33 1 2013-09-03 12 33 2 2019-01-04 13 33 3 2020-07-28 14 35 1 2015-10-21 15 35 2 2017-06-28 # 数据结构 data <- structure(list(group = c(1L, 1L, 10L, 10L, 12L, 12L, 31L, 31L, 31L, 33L, 33L, 33L, 33L, 35L, 35L), h_sequ = c(1L, 1L, 1L, 1L, 1L, 2L, 1L, 1L, 2L, 1L, 1L, 2L, 3L, 1L, 2L), date = structure(c(15426, 15426, 17099, 17099, 18803, 19130, 18228, 18228, 18710, 15951, 15951, 17900, 18471, 16729, 17345), class = "Date")), class = c("tbl_df", "tbl", "data.frame"), row.names = c(NA, -15L))
当前实现的局限
现有代码仅汇总每组的最小/最大日期,无法展示多日期组(如组33)的中间阶段变化:
library(ggplot2) library(ggalt) library(dplyr) data %>% summarise(start_date = min(date), end_date = max(date), .by = group) %>% ggplot(aes(x = start_date, xend = end_date, y = group)) + geom_dumbbell(color = "red3", size = 3)
优化方案
针对不同日期组的结构,先清洗数据并生成相邻日期的配对,再绘制组合哑铃图:
步骤说明
- 去重:保留每个
group+h_sequ对应的唯一日期,消除重复行干扰 - 生成日期配对:按
group分组,对h_sequ排序后,将每个日期与前一个日期配对(形成哑铃的起始/结束) - 处理单日期组:保留起始/结束日期相同的行,确保单日期组显示为一个点
完整代码
library(ggplot2) library(ggalt) library(dplyr) # 数据清洗与配对生成 dumbbell_data <- data %>% # 去重:每个group+h_sequ只保留唯一日期 distinct(group, h_sequ, date) %>% # 按group分组,对h_sequ排序 arrange(group, h_sequ) %>% group_by(group) %>% # 生成前一个日期作为起始日期,当前日期作为结束日期 mutate(start_date = lag(date, default = first(date))) %>% ungroup() %>% # 重命名结束日期,统一列名 rename(end_date = date) # 绘制组合哑铃图 ggplot(dumbbell_data, aes(x = start_date, xend = end_date, y = factor(group))) + # 绘制哑铃线和端点 geom_dumbbell(color = "gray50", size = 1, point.size = 3, colour_x = "blue", colour_xend = "darkred") + # 添加坐标轴标签 labs(x = "日期", y = "分组", title = "多阶段日期变化哑铃图") + # 优化主题 theme_minimal() + theme(axis.text.y = element_text(size = 10))
效果说明
- 单日期组(如组1、10):仅显示一个端点(起始/结束日期相同)
- 双日期组(如组12、31、35):显示一条哑铃线,连接两个日期
- 三日期组(如组33):显示两条哑铃线,分别连接1→2、2→3阶段的日期,完整展示所有阶段变化
内容的提问来源于stack exchange,提问作者TarJae
相关产品推荐
相关产品推荐

