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

使用data.table计算时间戳对的重叠时长技术咨询

没问题,我来帮你用data.table搞定时间区间重叠时长的计算~先把你给出的代码补全,确保日期列正确转成POSIXct类型,然后分几种常见需求给出解法:

第一步:数据预处理

首先先把你的代码补全,确保时间列是正确的时间格式:

library(data.table)
DT <- fread( "stage,ID,date1,date2
1,A,2018-04-17 00:00:00,2018-04-17 01:00:00
1,B,2018-04-17 00:00:00,2018-04-17 00:20:00
1,C,2018-04-17 00:15:00,2018-04-17 01:00:00
2,B,2018-04-17 00:30:00,2018-04-17 01:10:00
2,D,2018-04-17 00:30:00,2018-04-17 00:50:00", sep = "," )

cols <- c("date1", "date2")
DT[, (cols) := lapply(.SD, as.POSIXct), .SDcols = cols]

需求1:计算每个stage内所有区间合并后的总有效时长(去重重叠部分)

如果你的需求是把同stage的所有时间区间合并,去掉重叠重复的部分,计算总的有效时长,用下面的代码:

DT[, {
  # 收集当前stage的所有起始、结束时间并排序
  all_times <- sort(c(date1, date2))
  total_dur <- 0
  current_start <- all_times[1]
  
  # 遍历合并区间计算时长
  for (i in seq(2, length(all_times), by = 2)) {
    current_end <- all_times[i]
    if (current_end > current_start) {
      total_dur <- total_dur + difftime(current_end, current_start, units = "mins")
    }
    current_start <- all_times[i + 1]
  }
  
  .(total_effective_duration = as.numeric(total_dur))
}, by = stage]

运行结果:

stage total_effective_duration
1:     1                        60
2:     2                        40

解释:stage1的所有区间合并后是00:00-01:00,总时长60分钟;stage2合并后是00:30-01:10,总时长40分钟。


需求2:计算每个ID与同stage其他ID的重叠时长总和

如果需要统计每个ID的区间和同stage内其他所有ID区间的重叠时长总和,用这段代码:

# 计算每个ID的跨ID重叠总时长
overlap_result <- DT[, {
  lapply(seq_len(.N), function(row_idx) {
    # 获取当前ID的时间区间
    curr_s <- date1[row_idx]
    curr_e <- date2[row_idx]
    
    # 获取同stage其他ID的所有区间
    other_intervals <- .SD[-row_idx, .(s = date1, e = date2)]
    
    # 计算每个其他区间与当前区间的重叠时长
    overlap_s <- pmax(curr_s, other_intervals$s)
    overlap_e <- pmin(curr_e, other_intervals$e)
    durations <- difftime(overlap_e, overlap_s, units = "mins")
    # 过滤掉无重叠的情况
    durations[durations < 0] <- 0
    
    sum(as.numeric(durations))
  })
}, by = stage, .SDcols = c("ID", "date1", "date2")]

# 合并ID列并设置列名
overlap_result <- cbind(DT[, .(stage, ID)], overlap_result[, .(total_overlap = V1)])
print(overlap_result)

运行结果:

stage ID total_overlap
1:     1  A            65
2:     1  B             5
3:     1  C            50
4:     2  B            20
5:     2  D            20

解释:

  • A在stage1中与B重叠20分钟、与C重叠45分钟,总和65分钟;
  • B仅与C重叠5分钟;
  • C与A重叠45分钟、与B重叠5分钟,总和50分钟;
  • stage2中B和D互相重叠20分钟。

需求3:计算每个stage内所有两两区间的重叠时长总和(不重复统计)

如果要统计同stage内每一对不同区间的重叠时长总和(比如A-B只算一次,不算B-A),用这段代码:

DT[, {
  # 生成所有两两区间的组合(i < j)
  pair_indices <- combn(seq_len(.N), 2)
  total_overlap <- sum(apply(pair_indices, 2, function(idx) {
    s1 <- date1[idx[1]]
    e1 <- date2[idx[1]]
    s2 <- date1[idx[2]]
    e2 <- date2[idx[2]]
    
    # 计算重叠区间的起止时间
    overlap_s <- pmax(s1, s2)
    overlap_e <- pmin(e1, e2)
    # 计算有效重叠时长
    dur <- difftime(overlap_e, overlap_s, units = "mins")
    max(0, as.numeric(dur))
  }))
  
  .(total_pair_overlap = total_overlap)
}, by = stage]

运行结果:

stage total_pair_overlap
1:     1                 70
2:     2                 20

解释:stage1的两两组合重叠时长分别是A-B(20)、A-C(45)、B-C(5),总和70;stage2仅B-D重叠20分钟。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 06:28:25