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

基于月度均值填充时间序列缺失值(NA)的实现方法问询

用对应月份均值填充时间序列缺失值

这是个很常见的时间序列缺失值填充需求,用对应月份的季节均值来填充非常合理,下面给你两种实现方式,分别用base R和tidyverse工具包,你可以根据自己的习惯选择:

方法一:Base R 实现

不需要额外安装包,直接用R原生函数即可:

# 先构造完整的数据框
df <- data.frame(
  Date = seq(as.Date("1993-12-01"), as.Date("2005-05-01"), by = "1 month"),
  value = c(2.20000, 0.70000, 2.80000, 0.80000,1.20000, 1.50000, 0.90000 , NA, 0.80000, 1.70000, 2.40000, 1.60000, 4.00000, 4.40000, 2.50000, 1.10000, 2.40000, 1.10000, 3.70000, 6.40000, 7.00000, 2.90000, 3.00000, 3.60000, 4.90000, NA, 4.90000, 0.70000, 0.3000, 0.70000 ,0.37000,0.20000, 0.05000, 0.35000, 0.05000, 2.50000, 0.08000, 0.12000, 2.53000, 2.49000, 2.04000, 2.92000, 0.27000, 0.33000, 0.10000, 0.36000, 2.32000, 0.1900, 0.2300, 0.18000, 0.28000, 0.19500, 0.07300, 0.65000,0.30000)
)

# 从日期中提取月份(格式为两位字符串,比如"07"代表7月)
df$month <- format(df$Date, "%m")

# 按月份分组计算非缺失值的均值
monthly_means <- tapply(df$value, df$month, mean, na.rm = TRUE)

# 填充缺失值:将NA替换为对应月份的均值
df$value_filled <- ifelse(is.na(df$value), monthly_means[df$month], df$value)

关键步骤说明:

  • format(df$Date, "%m"):从日期列中提取月份信息,确保同月份的记录被分到同一组
  • tapply(..., mean, na.rm = TRUE):按月份分组计算均值,na.rm=TRUE会自动忽略组内的NA值
  • ifelse():判断每个值是否为NA,是则替换为对应月份的均值,否则保留原值

方法二:Tidyverse 实现

用dplyr做数据分组处理,lubridate简化日期操作,代码更直观易读:

# 先安装并加载所需包(如果没安装过的话)
# install.packages(c("dplyr", "lubridate"))
library(dplyr)
library(lubridate)

# 构造数据框(和base R部分一致)
df <- data.frame(
  Date = seq(as.Date("1993-12-01"), as.Date("2005-05-01"), by = "1 month"),
  value = c(2.20000, 0.70000, 2.80000, 0.80000,1.20000, 1.50000, 0.90000 , NA, 0.80000, 1.70000, 2.40000, 1.60000, 4.00000, 4.40000, 2.50000, 1.10000, 2.40000, 1.10000, 3.70000, 6.40000, 7.00000, 2.90000, 3.00000, 3.60000, 4.90000, NA, 4.90000, 0.70000, 0.3000, 0.70000 ,0.37000,0.20000, 0.05000, 0.35000, 0.05000, 2.50000, 0.08000, 0.12000, 2.53000, 2.49000, 2.04000, 2.92000, 0.27000, 0.33000, 0.10000, 0.36000, 2.32000, 0.1900, 0.2300, 0.18000, 0.28000, 0.19500, 0.07300, 0.65000,0.30000)
)

# 数据管道操作:提取月份 -> 分组 -> 填充缺失值
df_filled <- df %>%
  mutate(month = month(Date)) %>%  # 用lubridate提取月份(返回1-12的数字)
  group_by(month) %>%             # 按月份分组
  mutate(
    value_filled = ifelse(
      is.na(value), 
      mean(value, na.rm = TRUE), 
      value
    )
  ) %>%
  ungroup()                       # 取消分组

关键步骤说明:

  • lubridate::month(Date):直接返回日期对应的月份数字(1-12),比format()更简洁
  • dplyr的管道操作%>%:把数据处理步骤串联起来,逻辑更清晰
  • 分组后计算组内均值并填充,和base R逻辑一致,但代码可读性更强

注意事项

如果某个月份的所有值都是NA,mean(..., na.rm=TRUE)会返回NaN,这种情况你可以根据需求调整,比如改用全局均值或者相邻月份的均值来填充,但根据你的描述,序列只有少量缺失,这种极端情况应该不会出现。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 08:34:29