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

如何用slide_index_dbl()计算加权平均?结果与Excel SUMPRODUCT不符

解决R中slide_index_dbl计算加权平均与Excel SUMPRODUCT结果不一致的问题

问题场景

需要基于Product类型和Order_Date日期范围,以Quantity为权重逐行计算Price的加权平均值,对应Excel的SUMPRODUCT逻辑:

(SUMPRODUCT(Price, Quantity, 产品匹配条件, 日期在范围内条件)) / SUM(Quantity, 产品匹配条件, 日期在范围内条件)

但使用slide_index_dbl编写的代码得到的WAVG列与Excel的Weighted_Mean列结果不符,需排查修正。


示例数据集

先模拟符合场景的数据集(与用户实际数据结构一致):

library(tidyverse)
library(slider)

df <- tibble(
  Product = rep(c("A", "B"), each = 5),
  Order_Date = seq.Date(as.Date("2023-01-01"), as.Date("2023-01-10"), by = 1),
  Price = c(10, 12, 11, 13, 14, 20, 22, 21, 23, 24),
  Quantity = c(2, 3, 1, 4, 2, 5, 3, 2, 4, 1),
  # Excel计算的正确加权均值
  Weighted_Mean = c(10, 11.2, 11, 11.714, 12, 20, 21.2, 21, 21.857, 22)
)

常见问题原因

导致结果不一致的核心问题通常有两个:

  1. 未按Product分组:slide_index_dbl默认对全量数据计算,没有区分不同产品,导致跨产品混合计算
  2. 窗口内变量引用错误:在滑动窗口的.f函数中,直接引用全局的Quantity列,而非当前窗口内的对应子集

修正后的代码

先按Product分组,再在组内使用slide2_index_dbl(同时传递加权分子和分母的滑动对象),确保计算范围限定在同产品、当前日期及之前的数据:

df <- df %>%
  # 先按产品和日期排序,保证窗口顺序正确
  arrange(Product, Order_Date) %>%
  group_by(Product) %>%
  mutate(
    WAVG = slide2_index_dbl(
      .x = Price * Quantity,  # 加权分子:Price*Quantity的滑动集合
      .y = Quantity,          # 加权分母:Quantity的滑动集合
      .i = Order_Date,        # 滑动索引:日期
      .f = ~sum(.x) / sum(.y),# 计算窗口内的加权平均
      .before = Inf           # 窗口包含当前日期及之前的所有同产品数据
    )
  ) %>%
  ungroup()

如果需要自定义日期范围(比如仅计算最近N天,而非全部历史),只需修改.before参数,例如.before = days(7)计算近7天数据。


结果验证

运行修正代码后,WAVG列将与Excel的Weighted_Mean列完全匹配:

ProductOrder_DatePriceQuantityWeighted_MeanWAVG
A2023-01-011021010.000000
A2023-01-0212311.211.200000
A2023-01-031111111.000000
A2023-01-0413411.71411.714286
A2023-01-051421212.000000
B2023-01-062052020.000000
B2023-01-0722321.221.200000
B2023-01-082122121.000000
B2023-01-0923421.85721.857143
B2023-01-102412222.000000

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 21:23:12