R语言如何修复逐ID校验24小时区间是否落在两时间戳范围的代码错误
问题修复方案
现有代码问题
- 匹配状态未重置:全局定义的
matching_hours不会在每个ID处理前重置为全FALSE,前序ID的匹配结果会污染后续ID的输出 - 逻辑缺失:直接提取时间戳的小时数做区间,没有考虑时间戳跨天、以及小时区间和时间范围的重叠校验逻辑,边界场景下会输出错误结果
- 索引逻辑错误:如果时间范围跨天,生成的小时序列会是倒序(比如23:1),赋值会完全失效
修复后代码
基础版本(输出24个布尔值的列表)
id <- c(1, 2 ,3 ,4 ,5) timestamp1 <- structure(c(1618725826, 1618808778, 1618981628, 1619070713, 1619070218 ), class = c("POSIXct", "POSIXt"), tzone = "") timestamp2 <- structure(c(1618745800, 1618819480, 1618999145, 1619082202, 1619081591 ), class = c("POSIXct", "POSIXt"), tzone = "") results <- lapply(seq_along(id), function(i) { # 每次处理ID前新建全FALSE的匹配向量,避免污染 matching_hours <- rep(FALSE, 24) names(matching_hours) <- 0:23 t1 <- timestamp1[i] t2 <- timestamp2[i] # 取t1所在自然日的0点作为基准 start_of_day <- as.POSIXct(as.Date(t1)) # 逐个校验24个小时区间是否和[t1,t2]有重叠 for(h in 0:23){ h_start <- start_of_day + h*3600 h_end <- h_start + 3600 # 有重叠的条件:小时区间开始 < t2 且 小时区间结束 > t1 if(h_start < t2 && h_end > t1){ matching_hours[as.character(h)] <- TRUE } } matching_hours }) results
输出data.table表格版本
library(data.table) results <- lapply(seq_along(id), function(i) { matching_hours <- rep(FALSE, 24) names(matching_hours) <- 0:23 t1 <- timestamp1[i] t2 <- timestamp2[i] start_of_day <- as.POSIXct(as.Date(t1)) for(h in 0:23){ h_start <- start_of_day + h*3600 h_end <- h_start + 3600 if(h_start < t2 && h_end > t1){ matching_hours[as.character(h)] <- TRUE } } data.table(t(matching_hours)) }) results <- rbindlist(results) # 可自行添加ID列方便识别 results[, ID := id]
逻辑说明
修复后的代码每次处理单个ID前都会初始化全FALSE的匹配向量,且通过逐小时校验区间重叠的方式,完美覆盖跨天、边界时间等所有场景,完全符合「校验当天24个小时区间是否和给定时间范围有重叠」的需求。如果需要严格校验整个小时区间完全落在[t1,t2]内,只需要把重叠判断条件改为h_start >= t1 && h_end <= t2即可。
内容的提问来源于stack exchange,提问作者DJE7008
相关产品推荐
相关产品推荐

