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

在R中为各用户分组的数值型时间创建1小时时间间隔

在R语言中按用户分组划分连续1小时时间区间

针对你的需求(根据示例结果,实际规则为:按user分组,将每组内记录按时间戳排序后,相邻记录时间差不超过1小时的归为同一区间,超过则开启新区间,区间编号从1开始递增),可以用dplyr包实现:

步骤说明

  1. 按user分组,对每组的timestart进行排序,确保时间顺序正确。
  2. 计算每条记录与前一条记录的时间差,第一条记录的时间差设为0(与自身比较)。
  3. 判断时间差是否超过3600秒(1小时),超过则标记为新区间的起点。
  4. 对标记的新区间起点进行累计求和,加1后得到最终的区间编号。

代码实现

library(dplyr)

# 示例数据
df <- read.table(text="
user     timestart
1        1421286975
1        1421287343
1        1421470513
1        1421470513
1        1421471816
1        1421806839
2        1424217068
2        1424217150
2        1424218395", header=T, stringsAsFactors=F)

# 生成区间编号
result <- df %>%
  group_by(user) %>%
  arrange(timestart) %>%
  # 计算当前记录与前一条的时间差,第一条默认与自身比较
  mutate(time_diff = timestart - lag(timestart, default = first(timestart))) %>%
  # 标记是否开启新区间:时间差超过1小时则为1
  mutate(new_interval = as.integer(time_diff > 3600)) %>%
  # 累计求和得到区间编号,初始为1
  mutate(interval_1h = cumsum(new_interval) + 1) %>%
  # 移除中间变量
  select(-time_diff, -new_interval) %>%
  ungroup()

# 查看结果
print(result)

输出结果

# A tibble: 9 × 3
   user timestart interval_1h
  <int>     <int>       <dbl>
1     1 1421286975           1
2     1 1421287343           1
3     1 1421470513           2
4     1 1421470513           2
5     1 1421471816           2
6     1 1421806839           3
7     2 1424217068           1
8     2 1424217150           1
9     2 1424218395           1

补充说明

如果你的需求确实是以每组第一条记录为起始点,按固定1小时区间划分(即不管记录是否连续,只要距离组内第一条的时间在0-1小时为interval1,1-2小时为interval2,以此类推),可以使用以下代码:

result_fixed <- df %>%
  group_by(user) %>%
  mutate(
    # 计算与组内第一条记录的时间差(秒)
    diff_from_start = timestart - first(timestart),
    # 按1小时区间划分,加1得到区间编号
    interval_1h = floor(diff_from_start / 3600) + 1
  ) %>%
  select(-diff_from_start) %>%
  ungroup()

但该代码的结果与你提供的示例不符,因此推测你的真实需求是按连续时间块划分区间。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.07 06:10:52