R中用tidyverse实现逐方程工具变量控制函数回归的报错解决
分组控制函数法两阶段最小二乘(2SLS)回归实现
错误原因说明
你之前的代码存在三类核心问题:
- 语法问题:
do()函数内引用分组数据需用.而非.x,且lm类模型对象不能直接用unnest展开,必须先用broom包的转换函数处理为数据框格式 - 逻辑问题:第二阶段回归没有将第一阶段的残差纳入数据集,也没有加入回归公式,不符合控制函数法的设定
- 性能问题:直接存储全量
lm模型对象会占用大量内存,大数据场景下会触发存储不足报错
正确实现代码
你的第一阶段代码无需修改,第二阶段可按如下方式实现:
library(tidyverse) library(broom) # 第二阶段回归 df_fit_final <- df_fit %>% mutate( # 将第一阶段残差合并到对应分组的数据集 data_with_resid = map2(data, resids, ~ mutate(.x, v = .y)), # 跑第二阶段回归,加入第一阶段残差v作为控制变量 fit2 = map(data_with_resid, ~ lm(y ~ x + z2 + v, data = .x)), # 按需提取回归结果,避免存储全量lm对象 fit2_coef = map(fit2, tidy, conf.int = TRUE), # 提取系数、标准误、p值、置信区间 fit2_model_stats = map(fit2, glance) # 提取R方、F值等模型统计量 ) # 展开系数结果为普通数据框查看 df_coef_result <- df_fit_final %>% select(group, fit2_coef) %>% unnest(fit2_coef) # 展开模型统计量为普通数据框查看 df_stats_result <- df_fit_final %>% select(group, fit2_model_stats) %>% unnest(fit2_model_stats)
可选简化写法
如果你不需要保留中间的模型对象,也可以嵌套写map逻辑减少内存占用:
df_fit_simple <- df_fit %>% mutate( fit2_coef = map2(data, resids, ~ lm(y ~ x + z2 + v, data = mutate(.x, v = .y)) %>% tidy(conf.int = TRUE)) ) %>% select(group, fit2_coef) %>% unnest(fit2_coef)
内容的提问来源于stack exchange,提问作者timm
相关产品推荐
相关产品推荐

