如何在R中为不规则时间序列使用zoo包rollapply的by参数
按分钟聚合不规则时间序列(zoo包实现)
你的核心问题是不能按固定行数(60行)分组,因为数据存在缺失,属于不规则时间序列,必须基于时间戳本身进行分钟级分组,而非依赖观测数量。以下是高效的解决方案:
步骤1:正确创建带时间索引的zoo对象
先修正你的示例数据生成方式,确保zoo对象带有正确的时间戳索引:
library(zoo) library(lubridate) # 生成1秒间隔的时间序列 times <- seq(ymd_hms('2020-01-01 00:00:00'), ymd_hms('2020-01-01 00:02:00'), by = '1 sec') # 创建带时间索引的zoo对象 z <- zoo(runif(length(times), 1, 10), order.by = times) # 模拟缺失数据(可选,验证不规则序列处理) z <- z[-c(10, 20, 61, 80)] # 删除部分观测,模拟数据缺失
步骤2:按分钟分组聚合
推荐两种高效的分组方式,均为向量化操作,远快于for循环:
方法一:用floor_date截断时间到分钟
直接将每个时间戳向下取整到最近的分钟,以此作为分组依据:
# 将时间索引截断到分钟级别 min_groups <- floor_date(index(z), unit = 'minute') # 按分组计算均值 agg_result <- aggregate(z, by = min_groups, FUN = mean)
方法二:用cut划分时间区间
通过cut函数将时间序列划分为1分钟的区间,再分组聚合:
# 划分1分钟的时间区间 min_intervals <- cut(index(z), breaks = 'min') # 聚合计算,同时将区间标签转换为标准时间戳 agg_result <- aggregate(z, by = min_intervals, FUN = mean) index(agg_result) <- as.POSIXct(names(agg_result))
结果说明
运行上述代码后,agg_result会生成3行结果,分别对应2020-01-01 00:00:00、2020-01-01 00:01:00、2020-01-01 00:02:00三个分钟的均值,自动忽略数据缺失的情况(仅计算该分钟内存在的观测值)。
为什么你的原代码无效?
你之前的rollapply(zm, 60, mean, by = 60)是按固定行数分组,假设每60行对应1分钟,但当数据缺失时,行数和时间不再一一对应,会出现跨分钟取数的情况,自然无法得到正确的分钟级聚合结果。
内容的提问来源于stack exchange,提问作者user8229029
相关产品推荐
相关产品推荐

