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

R语言按国家分组通过线性回归批量填充多指标列缺失值

世界银行面板数据缺失值线性拟合填充解决方案

你之前嵌套循环结合动态mutate失效大概率是dplyr非标准求值的变量作用域问题,循环中生成的动态列名没有被正确解析。下面给出基于tidyverse嵌套数据框的稳定实现方案,完全规避变量作用域坑,可直接适配180个国家+50个指标的批量处理场景。


前置依赖

仅需安装加载tidyverse套件即可:

install.packages("tidyverse")
library(tidyverse)

可复现样例数据构造

先构造和你需求结构一致的样例数据集,方便验证效果:

set.seed(123)
# 样例数据:4个国家、21年数据、3个指标,含随机缺失值+全空指标列
sample_df <- expand.grid(
  country_code = c("CN", "US", "JP", "BR"),
  year = 2000:2020
) %>% 
  mutate(
    ind1 = rnorm(nrow(.), 10, 2),
    ind2 = rnorm(nrow(.), 50, 10),
    ind3 = rnorm(nrow(.), 100, 20)
  ) %>% 
  # 随机插入30%缺失值
  mutate(across(starts_with("ind"), ~ifelse(runif(nrow(.)) < 0.3, NA, .))) %>% 
  # 构造全空指标:日本的ind3全部设为NA,用于测试全空填充0逻辑
  mutate(ind3 = ifelse(country_code == "JP", NA, ind3))

核心填充代码

filled_df <- sample_df %>% 
  # 按国家分组,每个国家的独立数据打包为嵌套列
  nest(data = -country_code) %>% 
  mutate(
    # 遍历处理每个国家的数据集
    filled_data = map(data, function(country_df) {
      # 提取当前数据集内所有指标列(排除年份字段即可)
      ind_cols <- setdiff(colnames(country_df), "year")
      
      country_df %>% 
        # 批量遍历所有指标列做填充
        mutate(across(all_of(ind_cols), function(ind_vals) {
          # 规则1:当前国家的当前指标全为空,统一填充0
          if(all(is.na(ind_vals))) {
            return(rep(0, length(ind_vals)))
          }
          # 规则2:非全空则用年份拟合线性回归填充缺失值
          # 提取非缺失值作为训练集
          train_data <- tibble(y = ind_vals, x = country_df$year) %>% filter(!is.na(y))
          # 拟合单变量线性回归
          lm_model <- lm(y ~ x, data = train_data)
          # 生成全时间范围的预测值
          pred_vals <- predict(lm_model, newdata = tibble(x = country_df$year))
          # 原始值非空保留原始值,为空则用预测值填充
          coalesce(ind_vals, pred_vals)
        }))
    })
  ) %>% 
  # 解嵌套得到最终完整数据集
  unnest(filled_data) %>% 
  select(-data)

效果验证

# 验证日本的ind3全为0
filled_df %>% filter(country_code == "JP") %>% pull(ind3) %>% unique()
# 输出:0

# 验证最终数据集无缺失值
sum(is.na(filled_df))
# 输出:0

适配说明

如果你的指标列没有统一命名规则,只需修改ind_cols的筛选逻辑即可,比如除了country_code和year之外全为指标的话,代码调整为:

ind_cols <- setdiff(colnames(original_df), c("country_code", "year"))

如果需要对单指标非缺失值数量过少的场景做特殊处理(比如非缺失值<2时无法拟合回归,可自定义填充逻辑),可在全空判断后新增阈值判断即可。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.23 23:57:04