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

在R中计算含中断或重叠的日期区间总时长(车辆拥有年限统计)

计算存在重叠/中断的车辆拥有总年限(R实现)

需要统计每个人的车辆拥有总年限,核心规则:

  • 同一时间段拥有多辆车时,重叠部分不重复计算
  • 未拥有车辆的中断期,不计入总时长

示例数据

person <- c("Layla", "Layla", "Layla", "John", "John", "John", "Bo", "Bo")
car <- c("Volvo x", "Volvo y", "Fiat Q", "Tesla C", "Mazda H", "Ford W", "Honda 1", "Honda 2")
from_date <- as.Date(c("2000-01-01", "2009-01-02", "2011-01-05", "2000-08-01", "2004-07-09", "2008-01-01", "2001-01-01", "2003-07-01"))
end_date <- as.Date(c("2010-01-01", "2012-07-01", "2015-08-09", "2002-01-01", "2020-10-22", "2010-01-01", "2020-08-09", "2019-10-01"))

data <- data.frame(person, car, from_date, end_date)

数据结构预览:

person     car  from_date   end_date
1  Layla  Volvo x 2000-01-01 2010-01-01
2  Layla  Volvo y 2009-01-02 2012-07-01
3  Layla   Fiat Q 2011-01-05 2015-08-09
4   John  Tesla C 2000-08-01 2002-01-01
5   John  Mazda H 2004-07-09 2020-10-22
6   John   Ford W 2008-01-01 2010-01-01
7     Bo  Honda 1 2001-01-01 2020-08-09
8     Bo  Honda 2 2003-07-01 2019-10-01

解决方案(兼容R 4.3.1)

使用dplyr和lubridate包处理,无需依赖不兼容的genomicranger:

library(dplyr)
library(lubridate)

result <- data %>%
  # 按用户分组
  group_by(person) %>%
  # 按起始日期排序,方便合并区间
  arrange(from_date, .by_group = TRUE) %>%
  # 标记当前区间是否与上一个区间重叠或连续
  mutate(
    overlap = from_date <= lag(end_date, default = first(from_date) - 1),
    # 生成分组ID,用于合并区间
    group_id = cumsum(!overlap)
  ) %>%
  # 按合并后的区间分组,计算每个合并区间的起止日期
  group_by(person, group_id) %>%
  summarise(
    start = min(from_date),
    end = max(end_date),
    .groups = "drop_last"
  ) %>%
  # 计算每个用户的总年限,保留1位小数
  summarise(
    carowner_yearsum = round(as.numeric(difftime(end, start, units = "days")) / 365.25, 1),
    .groups = "drop"
  )

print(result)

预期输出

# A tibble: 3 × 2
  person carowner_yearsum
  <chr>             <dbl>
1 Bo                  19.5
2 John                 8.0
3 Layla               15.0

代码逻辑说明

  1. 分组排序:按用户分组后,对每个用户的车辆区间按起始日期排序,确保后续合并顺序正确。
  2. 标记重叠区间:通过比较当前区间的起始日期与上一个区间的结束日期,判断是否重叠或连续,生成合并分组ID。
  3. 合并区间:按合并分组ID聚合,得到每个用户的非重叠连续区间的起止日期。
  4. 计算总时长:将每个合并区间的天数转换为年(按年平均365.25天计算),求和后保留1位小数。

内容的提问来源于stack exchange,提问作者Sofie Abildgaard

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.17 15:54:57