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

R语言按年月日分组统计所有连续小时段长度方法

需求说明
  • 运行环境已加载依赖包:dplyr、tidyr、data.table、lubridate、sqldf
  • 待处理数据框结构参考:dataframe示例
  • 统计规则:按年、月、日维度统计所有独立连续小时段的长度;同一日期内存在多段不相连的连续小时时,需返回全部分段时长,不可仅统计当日最大连续时长
  • 期望输出字段:year、month、day、连续小时数
  • 现有代码问题:返回结果存在重复值,仅能统计最大连续时长,原代码如下:
consec <- df1 %>%
  add_count((hour)!= 1, name = 'Count') %>%
  group_by(year,month,day) 
实现方案

dplyr 实现(适配现有管道操作习惯)

核心逻辑是先按时间顺序排序,通过相邻行小时差值识别连续段边界,给每个独立连续段分配唯一ID后分组计数,不会遗漏同日多段连续时长,也不会产生重复值:

library(dplyr)

consec_result <- df1 %>%
  # 按年、月、日、小时升序排列,保证时间顺序正确
  arrange(year, month, day, hour) %>%
  # 先按自然日分组
  group_by(year, month, day) %>%
  mutate(
    # 识别连续段边界:首行记为新段起点,当前行小时与上一行差值不为1时也是新段起点
    is_new_seg = ifelse(row_number() == 1, TRUE, hour - lag(hour) != 1),
    # 累计新段起点次数,生成每个连续段的唯一ID
    seg_id = cumsum(is_new_seg)
  ) %>%
  # 按自然日+连续段ID分组,统计段时长
  group_by(year, month, day, seg_id) %>%
  summarise(
    连续小时数 = n(),
    .groups = "drop"
  ) %>%
  # 移除中间生成的段ID字段,保留要求的4个输出列
  select(year, month, day, 连续小时数)

data.table 实现(适合百万行以上大数据量场景,性能更高)

library(data.table)
# 转换为data.table格式
setDT(df1)

consec_result_dt <- df1[order(year, month, day, hour)][
  , .(连续小时数 = .N),
  # 直接在分组参数里生成连续段ID,省略中间赋值步骤
  by = .(year, month, day, seg_id = cumsum(c(TRUE, diff(hour) != 1)))
][, seg_id := NULL][]

注意:如果原始数据中同一个小时存在多条重复记录,需要先按year,month,day,hour去重后再运行上述代码,否则会把重复记录算入连续时长导致统计结果偏大。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 12:15:27