R中‘右向’与‘左向’滚动均值的区别及滞后n年均值计算方法
计算滞后前n年均值:左向 vs 右向窗口选择
嘿,我来帮你理清这个问题!首先直接给结论:你需要用左向滚动窗口(或者说“向后看”的窗口),因为你的需求是计算当前年份之前的n年数据的均值——也就是不包含当前年份,只取过去的n个观测值。
先给你掰扯清楚两种窗口的核心区别,避免搞混:
- 右向窗口:是“向前看”的,窗口会包含当前行和之后的行,这显然不符合你的需求(你要的是过去的年份,总不能用未来的数据来计算吧😉)。
- 左向窗口:是“向后看”的,窗口只包含当前行之前的所有目标行,正好对应你要的“滞后前n年”的范围。
接下来结合你的示例数据,给你几种实用的实现方法,都是R里常用的工具:
示例实现(以n=2为例,计算前2年均值)
先加载你给出的示例数据:
set.seed(1234) dat <- data.frame(year = c(1990:2010), x = rnorm(21))
方法1:用zoo包的rollapply(灵活控制窗口范围)
zoo包的rollapply可以自定义窗口范围,我们直接指定取当前行之前的n行(比如n=2,就用-(1:2)表示取当前行的前1和前2行):
library(zoo) # 新增列存储前2年均值 dat$x_lag2_mean <- rollapply(dat$x, width = list(-(1:2)), # 明确指定窗口为当前行之前的1-2行 FUN = mean, fill = NA) # 数据不足的位置填充NA
运行后你会看到,1990和1991年因为没有足够的前2年数据,会显示NA;1992年的值就是1990和1991年x的均值,完全符合预期。
方法2:用dplyr+slider(tidyverse风格,语法更直观)
如果你习惯用tidyverse的语法,slider包专门处理滚动窗口操作,可读性拉满:
library(dplyr) library(slider) dat <- dat %>% mutate(x_lag2_mean = slide_dbl(x, ~mean(.x), .before = 2, # 取当前行之前的2个观测值(不包含当前) .complete = TRUE)) # 只有窗口完整时才计算,否则返回NA
这里.before=2精准定义了窗口范围:当前行之前的2个数据;.complete=TRUE确保只有当窗口里凑齐2个数据时才计算均值,否则返回NA,完美匹配我们的需求。
为什么不用简单的lag+均值?
你示例里用的lag(dat$x,1)只能取单个滞后值,但要计算均值需要滚动窗口——因为你需要连续的n个滞后值的平均,而不是单个滞后值。滚动窗口工具能自动帮你处理窗口的滑动和缺失值填充,比手动循环高效多了。
验证结果是否正确
我们可以手动计算验证一下,比如看1992年的结果:
# 手动计算1990和1991年x的均值 manual_mean <- mean(dat$x[dat$year %in% c(1990,1991)]) # 和我们计算的x_lag2_mean对比 dat$x_lag2_mean[dat$year == 1992]
运行后会发现两者数值完全一致,说明我们的窗口选择和实现都是正确的!
内容的提问来源于stack exchange,提问作者Vedda




