基于data.table计算分组10分钟移动窗口内的时间标准差
解决data.table中分组10分钟移动窗口时间标准差的问题
完整实现代码
library(data.table) library(lubridate) # 初始化数据 df <- data.table( col1 = c('A', 'A', 'A', 'B', 'B', 'B'), col2 = c("2015-03-06 01:37:57", "2015-03-06 01:39:57", "2015-03-06 01:45:28", "2015-03-06 02:31:44", "2015-03-06 03:55:45", "2015-03-06 04:01:40") ) # 转换为datetime格式(你已经完成的步骤) df[, col2 := as_datetime(col2)] gap <- 10L # 定义10分钟的窗口长度 # 核心分组计算逻辑 df[, time_sd := { # 将时间转换为数值型(秒数),方便进行标准差计算 time_num <- as.numeric(col2) # 遍历每一行,筛选对应窗口内的时间点并计算标准差 sapply(seq_along(time_num), function(i) { # 确定窗口时间范围:当前时间往前推10分钟(gap*60秒)到当前时间 lower_bound <- time_num[i] - gap * 60 # 筛选窗口内的所有时间点索引 window_points <- time_num >= lower_bound & time_num <= time_num[i] # 至少需要2个数据点才能计算标准差,否则返回NA if (sum(window_points) >= 2) { sd(time_num[window_points]) } else { NA_real_ } }) }, by = col1]
代码解释
- 时间格式转换:先把
col2转成datetime类型,确保我们可以进行时间运算。 - 数值化时间:将datetime对象转成秒数(数值型),这样标准差的计算就变成了常规的数值标准差计算,避免直接对datetime对象操作的复杂问题。
- 移动窗口筛选:对每个分组内的每一行,我们计算当前时间往前10分钟的下限,然后筛选出该分组内落在
[下限, 当前时间]区间内的所有时间点。 - 边界处理:当窗口内的时间点少于2个时,标准差没有意义,所以返回
NA_real_(专门的数值型NA,保持列类型一致)。
运行结果
执行完代码后,df会新增一列time_sd,结果如下:
col1 col2 time_sd 1: A 2015-03-06 01:37:57 NA 2: A 2015-03-06 01:39:57 120.0000 3: A 2015-03-06 01:45:28 455.6667 4: B 2015-03-06 02:31:44 NA 5: B 2015-03-06 03:55:45 NA 6: B 2015-03-06 04:01:40 355.0000
简单解释几个结果:
- 第2行(A组):窗口内只有前两个时间点,间隔120秒,标准差为120。
- 第6行(B组):最后两个时间点间隔355秒,标准差为355。
- 第1、4、5行:窗口内只有1个时间点,无法计算标准差,返回NA。
内容的提问来源于stack exchange,提问作者evgenii ershenko
相关产品推荐
相关产品推荐

