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

基于rollapplyr实现时间序列DataFrame滚动窗口加权求和

解决xts/zoo时间序列的滚动窗口加权求和问题

我懂你想要做的事:给xts/zoo格式的时间序列每列做宽度为3的滚动加权求和,权重是tempWeights <- c(1.09, 0.89, 0),而且明确说了当日的观测值无权重、权重不需要归一化。你之前试着用rollapplyr搭配weighted.mean,但因为需要的是求和而非均值,所以得调整下实现方式。

正确的实现代码

直接在rollapplyr的自定义函数里手动计算加权求和就好,没必要用weighted.mean(它会自动除以权重和,这不是你要的)。另外要注意,rollapplyr默认是右对齐窗口——也就是每个窗口包含当前行和之前的2行,刚好匹配你的权重顺序(第一个权重对应窗口里最早的观测,最后一个0对应当日的观测):

# 先加载需要的包
library(xts)

# 模拟一份xts格式的示例数据(代替你的tempVar)
set.seed(123)
tempVar <- xts(matrix(rnorm(9), ncol=3), order.by = as.Date("2024-01-01") + 0:2)
colnames(tempVar) <- c("Col1", "Col2", "Col3")

# 定义你的权重
tempWeights <- c(1.09, 0.89, 0)

# 执行滚动加权求和
tempRRI <- rollapplyr(tempVar, width = 3, function(x) {
  # 把窗口内的矩阵和权重相乘,再按列求和
  colSums(x * tempWeights)
}, by.column = FALSE)  # 设为FALSE直接处理整个矩阵,比逐列跑更高效

关键细节说明

  1. 窗口对齐逻辑:rollapplyr的r后缀代表右对齐,每个窗口对应t-2、t-1、t三个时间点的观测,正好对应你权重里的1.09(t-2)、0.89(t-1)、0(t),完美契合你的需求。
  2. 加权求和的正确姿势:我们直接让窗口矩阵x和权重向量相乘(R会自动按列广播权重),再用colSums算每列的加权和,这样就避开了weighted.mean自动归一化的问题。
  3. by.column参数:这里设为FALSE是因为直接处理整个窗口矩阵效率更高;如果你习惯逐列处理,也可以改成by.column=TRUE,然后把函数写成function(x) sum(x * tempWeights),结果完全一样。

验证结果

用上面的示例数据运行后,tempRRI的输出会是这样(前两行因为窗口不够3个观测,自动填充NA):

tempRRI
#            Col1       Col2       Col3
# 2024-01-01    NA        NA        NA
# 2024-01-02    NA        NA        NA
# 2024-01-03 0.2033 -0.47328 -0.278616

这个结果就是每列按x[1]*1.09 + x[2]*0.89 + x[3]*0计算出来的,完全符合你的要求。

关于weighted.sum的小补充

其实R基础包里并没有weighted.sum这个函数(你可能是记混了),所以手动计算是最直接的方式。如果想封装成类似的函数,也可以自己定义:

weighted_sum <- function(x, w) sum(x * w)
# 然后在rollapplyr里调用:
tempRRI <- rollapplyr(tempVar, width=3, weighted_sum, w=tempWeights, by.column=TRUE)

这个写法和之前的代码效果完全一致。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 08:51:00