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

