使用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
相关产品推荐
相关产品推荐

