如何实现data.table中过去24小时的滚动求和?
过去24小时滚动求和的优雅解决方案
以下是几种适配不同场景的实现方式,按需选择即可:
方法1:data.table 原生高效实现
data.table的非等值自连接是处理这类时间窗口求和的高效方案,尤其适合数据量较大的场景:
library(data.table) # 先按时间排序,确保窗口计算逻辑正确 setorder(dt, Time) # 计算每个时间点过去24小时的amount总和 dt[, rolling_24h_sum := dt[.(start = Time - 24*3600, end = Time), on = .(Time >= start, Time <= end), sum(amount), by = .EACHI]$V1]
核心逻辑:对每一行的时间区间(当前时间往前推24小时到当前时间)做自连接,用by = .EACHI逐行计算该区间内的amount总和。
方法2:dplyr + slider 简洁实现
slider包专门针对时间滑动窗口做了优化,语法更直观,适合偏好tidyverse风格的用户:
library(dplyr) library(slider) dt %>% arrange(Time) %>% mutate(rolling_24h_sum = slide_index_sum( x = amount, i = Time, before = 24*3600, # 往前推24小时(单位:秒) after = 0, # 不包含当前时间之后的记录 complete = FALSE # 即使窗口不足24小时也计算现有记录的和 ))
slide_index_sum会自动根据Time索引匹配对应的时间窗口,不需要手动处理窗口长度,代码可读性拉满。
方法3:zoo 时间序列包实现
如果熟悉zoo这类老牌时间序列工具,也可以用它的滚动窗口函数:
library(zoo) # 先排序 dt_sorted <- dt[order(Time)] # 构造zoo对象,以Time为索引 z_obj <- zoo(dt_sorted$amount, dt_sorted$Time) # 计算24小时窗口的滚动求和 dt_sorted$rolling_24h_sum <- rollapplyr( z_obj, width = as.difftime(24, units = "hours"), FUN = sum, fill = NA, align = "right" # 窗口右端对齐当前时间 )
各方法适配场景
- 追求极致效率选data.table,大数据量下优势明显;
- 看重代码简洁易读选dplyr+slider;
- 已有zoo生态使用习惯选第三种方案。
内容的提问来源于stack exchange,提问作者dmp
相关产品推荐
相关产品推荐

