如何自动为含多起止点的哑铃图(Dumbbell Plot)添加间隙?
解决Tidyverse哑铃图多组线条间隙的自动化方法
先模拟一组复现问题的测试数据:
library(tidyverse) set.seed(123) df <- tibble( company = rep(c("A", "B", "C", "J", "K"), each = 4), type = rep(c("customers", "potential_customers"), each = 2, times = 5), date = c( # A公司的两组数据 ymd("2020-01-01"), ymd("2020-06-01"), ymd("2021-01-01"), ymd("2021-06-01"), # B公司一组数据 ymd("2020-03-01"), ymd("2020-09-01"), ymd("2020-03-01"), ymd("2020-09-01"), # C公司一组数据 ymd("2020-02-01"), ymd("2020-08-01"), ymd("2020-02-01"), ymd("2020-08-01"), # J公司两组数据 ymd("2020-04-01"), ymd("2020-10-01"), ymd("2021-04-01"), ymd("2021-10-01"), # K公司一组数据 ymd("2020-05-01"), ymd("2020-11-01"), ymd("2020-05-01"), ymd("2020-11-01") ), value = rnorm(20, 50, 10) )
原绘图代码会出现线条连续的问题:
df %>% ggplot(aes(x = date, y = value, color = type)) + geom_line(aes(group = company), linewidth = 1) + geom_point(size = 3) + facet_wrap(~company, scales = "free_x")
自动化添加间隙的核心方案
通过给每个公司的独立数据组分配唯一标识,让ggplot自动识别哪些点属于同一线条、哪些需要断开。用dplyr的分组累加即可完成自动化处理:
# 预处理数据:自动识别同公司同类型的多组数据,生成分组ID df_processed <- df %>% group_by(company, type) %>% # 当日期间隔超过设定阈值(这里用30天,可按需调整)时,生成新分组 mutate(group_id = cumsum(c(TRUE, diff(date) > days(30)))) %>% ungroup() # 重新绘图:用company+group_id的组合作为线条分组依据 df_processed %>% ggplot(aes(x = date, y = value, color = type)) + geom_line(aes(group = interaction(company, group_id)), linewidth = 1) + geom_point(size = 3) + facet_wrap(~company, scales = "free_x")
逻辑说明
cumsum(c(TRUE, diff(date) > days(30))):对每个公司的同类型数据,检查日期差,当间隔超过阈值时自动生成新的分组ID,无需手动指定目标公司。interaction(company, group_id):确保每个独立数据组有唯一的分组映射,ggplot会为每个分组单独绘制线条,自然形成间隙。- 该方法完全自动化,不管有多少公司存在多组数据,都能自动适配。
内容的提问来源于stack exchange,提问作者user63230
相关产品推荐
相关产品推荐

