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

在R中如何按数据子集基于历史值线性回归自动填充空单元格?

R语言实现按国家分组线性回归填充缺失值

核心逻辑说明

  • 按国家维度拆分数据,每个国家独立拟合模型
  • 仅用2000-2016年非空的Wood数据训练线性回归,有效数据不足2条的国家(含Wood全空的国家)直接跳过填充逻辑,保留原始数据
  • 仅填充Wood列为空的单元格,原有非空值保持不变
  • 自动兼容同一年份存在多条数据的场景

方法1:tidyverse简洁实现(推荐)

无需手动写循环,代码可读性高

# 没有安装包先执行 install.packages("tidyverse")
library(tidyverse)

df_filled <- df %>%
  # 按国家分组
  group_by(Country) %>%
  mutate(
    Wood = {
      # 提取当前国家2000-2016年的有效训练数据
      train_data <- cur_data() %>% filter(Year %in% 2000:2016 & !is.na(Wood))
      # 有效数据≥2条才拟合模型,否则保留原值
      if(nrow(train_data) >= 2) {
        model <- lm(Wood ~ Year, data = train_data)
        # 空值用预测值填充,非空值保留
        if_else(is.na(Wood), predict(model, newdata = cur_data()), Wood)
      } else {
        Wood
      }
    }
  ) %>%
  ungroup()

方法2:基础R循环实现(符合你初始的循环思路)

# 获取所有唯一国家列表
country_list <- unique(df$Country)
df_filled <- df

for (cntry in country_list) {
  # 定位当前国家的所有行
  country_rows <- which(df_filled$Country == cntry)
  # 筛选2000-2016年的非空训练数据
  train_data <- df_filled[country_rows, ] %>% filter(Year %in% 2000:2016 & !is.na(Wood))
  
  if(nrow(train_data) >= 2) {
    # 拟合线性模型
    lm_model <- lm(Wood ~ Year, data = train_data)
    # 定位当前国家Wood为空的行
    na_rows <- country_rows[is.na(df_filled$Wood[country_rows])]
    # 填充预测值
    df_filled$Wood[na_rows] <- predict(lm_model, newdata = df_filled[na_rows, ])
  }
  # 有效数据不足的国家直接跳过,不修改原有数据
}

补充说明

如果你需要对Wood取对数(你提到的ln函数)拟合,只需修改模型部分:

  • 拟合时改成lm(log(Wood) ~ Year, data = train_data)
  • 预测时改成exp(predict(model, newdata = ...))还原原值即可,注意要保证训练集的Wood值全部大于0,否则取对数会报错

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 20:33:00