跨午夜场景下的行间时间差计算与疼痛时长统计问题
解决跨午夜疼痛时长统计问题
针对跨午夜时间段拆分的需求,我们可以通过拆分跨天记录的方式,将单个跨天时间段拆分为当天结束和次日开始的两个分段,再分别计算时长,最终实现按天统计的目标。以下是完整解决方案:
步骤1:准备数据并添加下一个评估时间
首先为每条记录标记下一次评估的时间,同时提取当前记录的日期:
library(tidyverse) library(lubridate) df <- tibble( patient_id = c(1, 1, 1, 1, 1,1), time = as_datetime(c("2022-01-04 02:37:00", "2022-01-04 07:00:00", "2022-01-04 15:00:00", "2022-01-04 20:00:00", "2022-01-05 02:00:00", "2022-01-05 08:00:00")), pain_score = c("None", "Mild", "Mild", "Moderate", "None", "Mild") ) %>% arrange(patient_id, time) %>% group_by(patient_id) %>% mutate( next_time = lead(time), current_date = date(time) ) %>% ungroup()
步骤2:拆分跨午夜的记录
识别出跨天的时间段(current_date != date(next_time)),将这类记录拆分为两条:一条到当天午夜,一条从次日午夜开始:
# 生成拆分后的数据集 df_split <- df %>% # 处理非最后一条记录(有next_time的) filter(!is.na(next_time)) %>% rowwise() %>% # 生成时间段列表:如果跨天则拆分为两个时间段,否则保留原时间段 mutate( time_intervals = list( if (current_date != date(next_time)) { list( interval(time, floor_date(next_time, "day")), interval(floor_date(next_time, "day"), next_time) ) } else { list(interval(time, next_time)) } ) ) %>% unnest(time_intervals) %>% # 提取每个时间段的开始、结束时间和所属日期 mutate( start_time = int_start(time_intervals), end_time = int_end(time_intervals), day = date(start_time), duration_hours = as.numeric(end_time - start_time, units = "hours") ) %>% # 保留需要的列 select(patient_id, day, pain_score, start_time, end_time, duration_hours)
步骤3:按天统计疼痛时长
最后按患者、日期和疼痛评分汇总时长,验证每天总时长不超过24小时:
daily_pain_summary <- df_split %>% group_by(patient_id, day, pain_score) %>% summarise(total_duration_hours = sum(duration_hours), .groups = "drop") # 查看结果 print(daily_pain_summary)
示例输出结果
# A tibble: 5 × 4 patient_id day pain_score total_duration_hours <dbl> <date> <chr> <dbl> 1 1 2022-01-04 None 4.38 2 1 2022-01-04 Mild 8 3 1 2022-01-04 Moderate 4 4 1 2022-01-05 None 6 5 1 2022-01-05 Mild NA
验证2022-01-04的总时长:4.38 + 8 + 4 = 16.38小时,剩余的7.62小时可由前一天的延续评分补充(若有前一天数据),完全符合每日时长统计逻辑。
补充说明
- 对于数据集的最后一条记录(无后续评估时间),可根据需求自定义处理:比如默认评分持续到当天结束,或直接忽略(示例中过滤了
!is.na(next_time)的记录) - 借助
lubridate的interval和floor_date函数,可精准处理日期时间拆分,避免手动计算时区或日期差的错误
内容的提问来源于stack exchange,提问作者Benjamin Moran
相关产品推荐
相关产品推荐

