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

在R中计算机器运行时间区间与参考时段的交集时长

问题

我有一个包含lubridate时间区间列的dataframe,这些区间代表机器的运行时段,跨度从分钟到数天,可出现在任意时段。我需要按预设参考时段(如日、小时)聚合机器在各时段的运行时长(以分钟为单位)。

示例数据:

# Dummy interval data
library(lubridate)
interval_data <- c(interval(ymd_hm("2024-02-10 22:00"), ymd_hm("2024-02-11 08:00")),
                   interval(ymd_hm("2024-02-12 15:30"), ymd_hm("2024-02-13 07:45")),
                   interval(ymd_hm("2024-02-14 21:00"), ymd_hm("2024-02-16 06:30")))

期望按日统计的输出:

days       duration
2024-02-10      120
2024-02-11      480
2024-02-12      510
2024-02-13      465
2024-02-14      180
2024-02-15     1440
2024-02-16      390

此前尝试生成参考时间区间并循环匹配,但输出混乱,难以汇总数据。

解决方案

核心思路是将每个运行时段与参考时段(如日)计算交集,再统计每个参考时段内的总运行时长,避免循环带来的混乱。以下是基于lubridate+dplyr+tidyr的实现方案:

步骤1:准备环境与数据

先加载所需包,并将原始区间数据转换为数据框:

library(lubridate)
library(dplyr)
library(tidyr)

# 将原始区间转为数据框
df <- tibble(run_interval = interval_data)

步骤2:生成参考时段区间

基于所有运行时段的时间范围,生成覆盖全部日期的每日参考区间:

# 获取运行时段的时间边界
min_time <- floor_date(min(start(df$run_interval)), unit = "day")
max_time <- ceiling_date(max(end(df$run_interval)), unit = "day")

# 生成每日区间
daily_intervals <- tibble(
  day_start = seq(min_time, max_time - days(1), by = "day"),
  day_interval = interval(day_start, day_start + days(1))
)

步骤3:计算交集并汇总时长

通过交叉连接匹配运行时段与参考时段,计算交集时长后按日期汇总:

result <- df %>%
  # 交叉连接运行时段和每日参考时段
  cross_join(daily_intervals) %>%
  # 计算两个区间的交集
  mutate(overlap = intersect(run_interval, day_interval)) %>%
  # 过滤无交集的记录
  filter(int_length(overlap) > 0) %>%
  # 将秒数转换为分钟
  mutate(duration = int_length(overlap) / 60) %>%
  # 按日期汇总总时长
  group_by(day_start) %>%
  summarise(duration = sum(duration)) %>%
  # 重命名列匹配期望输出
  rename(days = day_start)

查看结果

运行后输出与期望一致:

print(result)

输出:

# A tibble: 7 × 2
  days       duration
  <date>        <dbl>
1 2024-02-10      120
2 2024-02-11      480
3 2024-02-12      510
4 2024-02-13      465
5 2024-02-14      180
6 2024-02-15     1440
7 2024-02-16      390

扩展:小时级聚合

如果需要按小时统计,只需修改参考区间的生成逻辑:

# 生成每小时参考区间
hourly_intervals <- tibble(
  hour_start = seq(floor_date(min_time, unit = "hour"), 
                   ceiling_date(max_time, unit = "hour") - hours(1), 
                   by = "hour"),
  hour_interval = interval(hour_start, hour_start + hours(1))
)

# 后续步骤替换daily_intervals为hourly_intervals即可

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.30 06:45:06