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

如何计算无NA值的年日序循环7日中心滚动均值?

实现循环年日序的无NA值7日中心滚动均值

方法一:利用rollapply的circular参数(推荐)

zoo包的rollapply函数支持circular=TRUE参数,可直接处理循环序列的滚动计算,无需手动调整数据:

library(tidyverse)
library(zoo)

set.seed(321)

aa <- data.frame(
  doy = seq(1,365,1),
  value = round(rnorm(365,30,5))
)

# 计算循环的7日中心滚动均值
bb <- aa %>%
  mutate(movingAVG = round(rollapply(value, width = 7, FUN = mean, 
                                     align = 'center', circular = TRUE)))

# 查看前6行结果
head(bb)
#>   doy value movingAVG
#> 1   1    39        30
#> 2   2    26        30
#> 3   3    29        31
#> 4   4    29        31
#> 5   5    29        30
#> 6   6    31        31

# 查看后6行结果
tail(bb)
#>     doy value movingAVG
#> 360 360    24        30
#> 361 361    38        29
#> 362 362    30        29
#> 363 363    20        28
#> 364 364    26        29
#> 365 365    29        30

原理说明

circular=TRUE会将输入的value序列视为循环结构:

  • 当计算开头日期(如doy=1)的滚动均值时,窗口自动从序列末尾取doy=363、364、365的数据补全前3天;
  • 当计算末尾日期(如doy=365)的滚动均值时,窗口自动从序列开头取doy=1、2、3的数据补全后3天;
  • 最终每个日期都能得到完整的7日窗口均值,无NA值。

方法二:手动扩展数据实现循环逻辑

如果需要更直观地控制窗口数据,可通过扩展原始数据的方式实现:

library(tidyverse)
library(zoo)

set.seed(321)

aa <- data.frame(
  doy = seq(1,365,1),
  value = round(rnorm(365,30,5))
)

# 扩展数据:开头添加原数据最后3行,结尾添加原数据最前3行
extended_aa <- bind_rows(tail(aa, 3), aa, head(aa, 3))

# 计算中心7日滚动均值
extended_aa <- extended_aa %>%
  mutate(movingAVG = round(rollmean(value, k = 7, align = 'center')))

# 截取中间365行,得到原日期对应的无NA结果
bb <- extended_aa %>% slice(4:(365+3))

# 验证结果(与方法一一致)
head(bb)
tail(bb)

原理说明

扩展数据后,原序列的首尾日期在新序列中处于中间位置,其滚动窗口会包含来自原序列另一端的补全数据,最终截取中间部分即可得到符合循环逻辑的完整结果。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 06:00:01