Stata中DID回归变量遗漏原因及代码合理性咨询
Stata双重差分(DID)模型变量遗漏与代码逻辑验证
问题背景
使用Stata处理NIBRS数据,构建双重差分回归模型,目的是估算爱达荷州**Payette(4619)、Twin Falls(4635)、Latah(4649)三个县在邻州大麻合法化后,涉毒逮捕是否增加;对照组为Blaine(4551)、Bonneville(4562)、Freemont(4593)**三个县,以agency_id标识各县。
当前遇到的问题:
- 运行代码时
did_WA、did_OR、did_NV变量被回归模型遗漏 - 需要验证代码逻辑是否合理,是否存在必要数据点丢失的情况
原代码
clear all set more off clear // 创建数据文件夹路径 global source = "\\netapp.bcis.bates.edu\slaski\Crime_final" // 循环将各年份的csv文件转为dta格式 forvalues y = 2011/2018{ cd "$source\ID-`y'" foreach i in incident month OFFENSE { import delim NIBRS_`i'.csv, clear save NIBRS_`i'.dta, replace clear } } // 循环合并每年的incident、month、offense数据 forvalues y = 2011/2018{ cd "$source\ID-`y'" use NIBRS_incident.dta // 合并incident与month数据(多对一) merge m:1 nibrs_month_id using NIBRS_month.dta., force drop if _merge ==2 drop _merge // 合并incident与offense数据(一对多) merge 1:m incident_id using NIBRS_offense.dta, force save NIBRS_MERGE.dta,replace clear } // 合并所有年份的数据集 cd "$source\ID-2011" use NIBRS_merge.dta forvalues y = 2011/2018{ cd "$source\ID-`y'" append using NIBRS_merge.dta, force } cd "$source" save finalNIBRS_merge.dta, replace // 删除缺失观测 use finalNIBRS_merge.dta drop if nibrs_month_id==. | month_num==. | incident_id==. |data_year==. // 筛选涉毒案件与目标县 keep if (offense_type_id == 16) keep if inlist(agency_id, 4619, 4635, 4649, 4551, 4562, 4593) // 按县-月份聚合逮捕数 gen crime=1 gen year_month = ym(data_year, month_num) collapse(sum) crime, by (year_month agency_id) format year_month %tm gen DRUG_arrests = crime == 1 // 生成邻州合法化前后标识变量 gen post_legalization_WA = year >=2012 replace post_legalization_WA = year >=2018 if agency_id == 4619 gen post_legalization_OR = year >=2015 replace post_legalization_OR = year >=2018 if agency_id == 4649 gen post_legalization_NV = year >=2016 replace post_legalization_NV = year >=2018 if agency_id == 4635 gen post_legalization = (year >= 2012) if inlist(agency_id, 4619,4635,4649) replace post_legalization = (year >= 2018) if inlist(agency_id, 4619) & (year >= 2018) replace post_legalization = (year >= 2015) if inlist(agency_id, 4649) & (year >= 2015) replace post_legalization = (year >= 2016) if inlist(agency_id, 4635) & (year >= 2016) gen pre_period = (year < 2012) gen post_period = (year >= 2012) // 定义处理组/对照组 gen treatment = 1 if agency_id== 4619 | agency_id== 4635 | agency_id== 4649 replace treatment = 0 if agency_id== 4551 | agency_id== 4562 | agency_id== 4593 gen control_vars = treatment == 0 // 生成DID交互项 gen did_WA = treatment * post_legalization_WA gen did_OR = treatment * post_legalization_OR gen did_NV = treatment * post_legalization_NV reg DRUG_arrests did_WA did_OR did_NV control_vars i.year
问题分析与修正建议
1. 变量遗漏的核心原因
did_WA等变量被回归模型遗漏,本质是**year变量不存在**:
- 在
collapse(sum) crime, by (year_month agency_id)步骤后,原始数据中的data_year被丢弃,后续代码误用的year变量根本不存在,导致post_legalization_WA等变量全为缺失值,交互项did_WA等也随之缺失,回归时自动被排除。
2. 代码逻辑关键问题
(1)数据合并与append错误
- 初始append步骤先加载2011年数据,再循环append 2011-2018年数据,导致2011年数据重复加载两次,出现冗余观测。
- merge过程中直接删除
_merge变量且丢弃匹配失败的观测,无法验证合并质量,可能丢失有效数据。
(2)被解释变量定义错误
gen DRUG_arrests = crime ==1仅将“恰好1次逮捕”的观测设为1,逮捕次数>1的观测会被设为0,完全违背研究逻辑,应改为:
// 若关注是否有涉毒逮捕(二元变量) gen DRUG_arrests = (crime > 0) // 若关注逮捕次数(计数变量) gen DRUG_arrests = crime
(3)时间变量缺失与逻辑冗余
- 未从
year_month中提取年份,需补充:
gen year = year(year_month)
post_legalization的生成逻辑冗余,且未区分不同处理县对应的邻州合法化时间,应针对每个处理县单独定义post变量。
(4)DID模型设定错误
- 标准DID模型需包含
treatment主效应、post主效应及交互项,当前直接放入交互项+control_vars(与treatment完全共线性),不符合双重差分的识别逻辑。 - 回归中使用
i.year但year变量不存在,应改为基于year_month的时间固定效应,或提取year后使用i.year。
(5)面板数据完整性缺失
collapse后未补全“零逮捕”的月份观测,导致样本仅包含有逮捕记录的月份,存在严重样本选择偏差,需用fillin补全面板:
fillin agency_id year_month replace crime = 0 if crime == .
3. 修正后的核心代码片段示例
// 从year_month中提取年份 gen year = year(year_month) format year_month %tm // 补全面板,保留零逮捕月份 fillin agency_id year_month replace crime = 0 if crime == . gen DRUG_arrests = (crime > 0) // 定义处理组/对照组 gen treatment = 0 replace treatment = 1 if inlist(agency_id, 4619, 4635, 4649) // 针对每个处理县定义对应的合法化后标识变量 gen post_WA = (year >=2012) if agency_id ==4619 replace post_WA = (year >=2018) if agency_id ==4619 & year >=2018 gen post_OR = (year >=2015) if agency_id ==4649 replace post_OR = (year >=2018) if agency_id ==4649 & year >=2018 gen post_NV = (year >=2016) if agency_id ==4635 replace post_NV = (year >=2018) if agency_id ==4635 & year >=2018 // 生成DID交互项 gen did_WA = treatment * post_WA gen did_OR = treatment * post_OR gen did_NV = treatment * post_NV // 标准DID回归(加入个体+时间固定效应,稳健标准误) reg DRUG_arrests did_WA did_OR did_NV i.agency_id i.year, robust
内容的提问来源于stack exchange,提问作者SJJ
相关产品推荐
相关产品推荐

