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

如何在R中基于最近年份的值自动填充NA值

R语言按规则填充数据框NA值的解决方案

问题分析

你的需求是:

  • 若NA所在年份恰好处于两个非NA年份的正中间,用这两个年份的均值填充
  • 其余NA用最近的非NA值填充(前侧NA取前面最近值,后侧NA取后面最近值)

之前的代码问题在于,na.approx(.)会对所有剩余NA执行线性插值,覆盖了case_when的处理逻辑,导致所有NA都被线性填充,不符合预期。

解决方案

我们可以分步骤标记中间年份,再分别处理不同类型的NA,这里使用dplyr和zoo包实现:

library(dplyr)
library(zoo)

# 构造示例数据(模拟你的数据结构)
df <- tibble(
  year = 2009:2015,
  Essonne = c(10, NA, NA, NA, NA, NA, 20)
)

# 执行填充逻辑
df_filled <- df %>%
  mutate(
    # 向前填充:取当前位置之前最近的非NA值
    ffill = na.locf(Essonne),
    # 向后填充:取当前位置之后最近的非NA值
    bfill = na.locf(Essonne, fromLast = TRUE),
    # 获取当前位置前后最近的非NA年份
    prev_non_na_year = na.locf(year[!is.na(Essonne)]),
    next_non_na_year = na.locf(year[!is.na(Essonne)], fromLast = TRUE),
    # 判断是否为两个非NA年份的正中间
    is_middle_year = (year - prev_non_na_year) == (next_non_na_year - year),
    # 按规则填充NA
    Essonne_filled = case_when(
      !is.na(Essonne) ~ Essonne,  # 非NA值保留
      is_middle_year ~ (ffill + bfill) / 2,  # 中间年份用均值
      (year - prev_non_na_year) < (next_non_na_year - year) ~ ffill,  # 离前面更近取前值
      TRUE ~ bfill  # 离后面更近取后值
    )
  ) %>%
  # 保留核心列(可根据需求调整)
  select(year, Essonne, Essonne_filled)

# 查看结果
print(df_filled)

运行结果

# A tibble: 7 × 3
   year Essonne Essonne_filled
  <int>   <dbl>          <dbl>
1  2009      10             10
2  2010      NA             10
3  2011      NA             10
4  2012      NA             15
5  2013      NA             20
6  2014      NA             20
7  2015      20             20

关键逻辑说明

  1. 向前/向后填充:通过na.locf分别获取每个位置前后最近的非NA值,作为填充的参考基准
  2. 中间年份判断:通过计算当前年份与前后非NA年份的差值是否相等,标记出需要用均值填充的位置
  3. 条件填充:用case_when分情况处理,优先保留原始值,再处理中间年份,最后按距离远近选择最近值填充

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 18:50:28