R中含内生变量交互项的固定效应模型估计问题求解
问题解决:fixest中含内生变量交互项的固定效应2SLS实现
错误原因
Endogenous variables should not be used as exogenous regressors错误的核心是:同一个变量既被作为外生因子纳入主回归的交互项,又被指定为内生变量。你的代码里,gas_price(对应数据中的gas_week_price)作为交互项部分出现在主回归公式,同时又在工具变量段被声明为内生变量,这违反了2SLS规则——内生变量及其所有交互项都必须归入内生变量集合,不能作为外生因子处理。
Fixest包内的解决方案
要在fixest中实现含内生变量交互项的固定效应2SLS,需将所有包含内生变量的交互项都列为内生变量,并为这些交互项构造对应工具变量(即工具变量与外生变量的交互项)。具体步骤如下:
1. 构造交互项
手动生成所有涉及内生变量的交互项,以及对应的工具变量交互项:
library(dplyr) library(fixest) # 假设用数据中的weekly_ban_dummy作为policy_dummy,weekly_event作为holiday_dummy seasonal_data <- seasonal_data %>% mutate( # 内生变量相关交互项 policy_gas = weekly_ban_dummy * gas_week_price, holiday_gas = weekly_event * gas_week_price, policy_holiday_gas = weekly_ban_dummy * weekly_event * gas_week_price, # 工具变量相关交互项(工具变量crude_oil与外生虚拟变量的交互) policy_crude = weekly_ban_dummy * crude_oil, holiday_crude = weekly_event * crude_oil, policy_holiday_crude = weekly_ban_dummy * weekly_event * crude_oil )
2. 运行2SLS模型
将所有含内生变量的项纳入工具变量段,不含内生变量的外生交互项仍放在主回归公式:
model <- feols( # 主回归:外生变量(含不含内生变量的交互项) + 固定效应 log(weekly_avg_price) ~ weekly_ban_dummy + weekly_event + weekly_ban_dummy*weekly_event | item_id + month + store_id | # 内生变量集合:原内生变量 + 所有含内生变量的交互项 gas_week_price + policy_gas + holiday_gas + policy_holiday_gas ~ # 工具变量集合:原工具变量 + 所有对应交互项的工具 crude_oil + policy_crude + holiday_crude + policy_holiday_crude, data = seasonal_data, vcov = "DK", panel.id = c("panel_id", "week_start") ) summary(model)
其他R包的替代方案
如果fixest的设定方式不符合需求,可使用以下包实现相同功能:
1. AER包(ivreg)
AER的ivreg函数支持工具变量回归,结合sandwich包可计算DK标准误:
library(AER) library(sandwich) library(lmtest) # 将固定效应转为因子变量 seasonal_data <- seasonal_data %>% mutate( item_id = factor(item_id), month = factor(month), store_id = factor(store_id) ) # 运行IV回归 model_ivreg <- ivreg( log(weekly_avg_price) ~ weekly_ban_dummy*weekly_event*gas_week_price + item_id + month + store_id | # 外生变量 + 固定效应 + 工具变量交互项 weekly_ban_dummy*weekly_event + item_id + month + store_id + crude_oil*weekly_ban_dummy*weekly_event, data = seasonal_data ) # 计算并展示DK聚类标准误 coeftest(model_ivreg, vcov = vcovCL, cluster = ~panel_id + week_start)
2. plm包
plm包专门处理面板数据,支持固定效应下的IV回归:
library(plm) # 转换为面板数据格式 pdata <- pdata.frame(seasonal_data, index = c("panel_id", "week_start")) # 运行固定效应IV回归 model_plm <- plm( log(weekly_avg_price) ~ weekly_ban_dummy*weekly_event*gas_week_price | weekly_ban_dummy*weekly_event + crude_oil*weekly_ban_dummy*weekly_event, data = pdata, model = "within", # 固定效应 inst = ~crude_oil*weekly_ban_dummy*weekly_event, method = "twostage" ) # 添加DK标准误 summary(model_plm, vcov = vcovDK(model_plm, type = "sss"))
内容的提问来源于stack exchange,提问作者Tim George




