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
相关产品推荐
相关产品推荐

