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

使用ggplot2绘制单变量持续时间时间序列数据的高效方案咨询

高效实现方案

你原来的逐天打标记的方案在日期跨度大、企业样本量高时会产生极高的内存占用,计算效率很低,这里提供两种更优的实现思路:

方法1:事件点增量累加(最高效,全场景通用)

核心逻辑:仅用事件的起止节点做增量统计,不需要生成逐行逐天的宽表,内存占用极低,计算速度不受日期跨度影响:

  • 每条事件拆为两个节点:事件开始当天计数+1,事件结束次日计数-1(因为结束当天仍属于事件存续期)
  • 按日期聚合所有增量后累加,即可得到每日存续企业数

对应的R实现代码:

library(tidyverse)
library(lubridate)

# 示例数据生成
set.seed(123)
df <- data.frame(id = sample(100:500, 100, replace = F))
df$start <- sample(seq(as.Date('2020/01/01'), as.Date('2020/12/31'), by="day"), 100)
df$end <- df$start + sample(1:50, replace = T)

# 增量统计计算
daily_count <- df %>%
  # 拆分起止节点
  pivot_longer(cols = c(start, end), names_to = "type", values_to = "date") %>%
  mutate(change = ifelse(type == "start", 1, -1),
         # 结束节点调整为次日
         date = if_else(type == "end", date + days(1), date)) %>%
  # 按日期聚合增量
  group_by(date) %>%
  summarise(change = sum(change)) %>%
  # 补全所有日期
  complete(date = seq.Date(min(df$start), max(df$end), by = "day"), fill = list(change = 0)) %>%
  # 累加得到当日存续数
  mutate(cnt = cumsum(change))

方法2:非等值连接统计(适合结构化查询场景)

如果用data.table的非等值连接语法,也可以快速完成范围统计,代码更简洁:

library(data.table)
setDT(df)
# 生成完整日期序列
date_dt <- data.table(date = seq(min(df$start), max(df$end), by = "day"))
# 非等值连接统计每日符合条件的企业数
daily_count <- df[date_dt, on = .(start <= date, end >= date), .N, by = .EACHI]
setnames(daily_count, c("date", "end", "cnt"))
daily_count <- daily_count[, .(date, cnt)]

结果可视化

得到每日统计结果后直接绘图即可:

ggplot(daily_count, aes(x = date, y = cnt)) +
  geom_line(color = "#2c3e50") +
  labs(x = "日期", y = "存续事件企业数量") +
  theme_minimal()

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 05:51:00