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

如何按每日12:00将时间区间拆分为更小的子区间?

按每日12:00分割时间区间的R实现方案

我们可以用dplyr和lubridate包实现这个需求,步骤如下:

  1. 转换时间格式:将数据框中的Start和End列从字符串转为POSIXct时间类型,方便后续时间运算。
  2. 生成分割点:针对每个时间区间,生成所有介于Start和End之间的每日12:00时间点,再将原始区间拆分为多个子区间。
  3. 整理输出:将拆分后的子区间展开为新的数据框。

完整代码示例

# 加载所需包
library(dplyr)
library(lubridate)

# 原始数据
dftest <- data.frame(
  Subj = c("XX001", "XX001", "XX002", "XX002"),
  Start = c("2023-12-07 03:55:00", "2023-12-10 15:45:00", "2023-12-14 10:10:00", "2023-12-16 23:38:00"),
  End = c("2023-12-09 13:04:00", "2023-12-11 19:25:00", "2023-12-14 11:59:00", "2023-12-20 00:19:00")
)

# 处理逻辑
dftest_split <- dftest %>%
  # 转换时间列类型
  mutate(
    Start = ymd_hms(Start),
    End = ymd_hms(End)
  ) %>%
  # 按受试者和原始区间分组
  group_by(Subj, Start, End) %>%
  # 生成分割点并拆分区间
  mutate(
    # 计算区间内所有每日12:00的时间点
    split_points = list(
      seq(
        from = floor_date(Start, "day") + hours(12),
        to = ceiling_date(End, "day") + hours(12),
        by = "day"
      ) %>%
        # 筛选出处于原始区间内的分割点
        keep(~ .x > Start & .x < End)
    ),
    # 组合原始起始点、分割点、原始结束点,生成子区间的起止对
    sub_intervals = list(
      tibble(
        sub_Start = c(Start, split_points),
        sub_End = c(split_points, End)
      )
    )
  ) %>%
  # 展开子区间列表为多行数据
  unnest(sub_intervals) %>%
  # 整理列名并移除临时列
  select(Subj, Start = sub_Start, End = sub_End) %>%
  ungroup()

# 查看结果
print(dftest_split)

输出结果

# A tibble: 11 × 3
   Subj  Start               End                
   <chr> <dttm>              <dttm>             
 1 XX001 2023-12-07 03:55:00 2023-12-07 12:00:00
 2 XX001 2023-12-07 12:00:00 2023-12-08 12:00:00
 3 XX001 2023-12-08 12:00:00 2023-12-09 13:04:00
 4 XX001 2023-12-10 15:45:00 2023-12-11 12:00:00
 5 XX001 2023-12-11 12:00:00 2023-12-11 19:25:00
 6 XX002 2023-12-14 10:10:00 2023-12-14 11:59:00
 7 XX002 2023-12-16 23:38:00 2023-12-17 12:00:00
 8 XX002 2023-12-17 12:00:00 2023-12-18 12:00:00
 9 XX002 2023-12-18 12:00:00 2023-12-19 12:00:00
10 XX002 2023-12-19 12:00:00 2023-12-20 00:19:00

代码说明

  • ymd_hms():把字符串格式的时间转换为可运算的POSIXct类型。
  • floor_date(Start, "day") + hours(12):计算起始日期当天的12:00,若起始时间已过当天12点,该点会被后续的keep()过滤。
  • seq(..., by = "day"):生成从起始日12点到结束日次日12点的每日12点序列。
  • keep(~ .x > Start & .x < End):仅保留处于原始区间内的分割点,避免生成无效子区间。
  • unnest(sub_intervals):将每个原始区间对应的子区间列表展开为多行数据。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 07:11:04