Day 05 · 手写教程
Chow 检验
两组系数看着不一样,不等于真的有差
Chow 检验是什么?
Chow 检验用于判断两组样本中的回归系数是否真的不同。它解决的是一个很常见的误读:一组显著、另一组不显著,并不等于两组系数显著不同。要判断“差异是否显著”,必须直接检验两组系数差。
本案例按产权性质分组,比较数字普惠金融对企业创新的影响在两类企业之间是否不同。
这个案例怎么做?
最直接的做法是在同一个模型中加入交互项:dfi_index × SOE。如果交互项显著,说明国企和民企之间的 DFI 斜率存在统计意义上的差异。也可以用分组回归后再做差异检验,但核心思想都是检验“系数差是否等于 0”。
结果应该怎么读?
本案例的组间系数差为 -0.000924,标准误为 0.080567,p 值为 0.9909。这个 p 值非常大,说明不能拒绝两组系数相等。也就是说,虽然分组回归表里两组数字可能不完全一样,但没有证据表明这种差异具有统计显著性。
论文里怎么写?
可以写:进一步通过 Chow/交互项检验考察产权性质下的组间差异。结果显示,组间系数差为 -0.000924,p=0.9909,未能拒绝两组核心系数相等的原假设,说明本案例中数字普惠金融对创新的影响未表现出显著产权异质性。
常见错误
不要写“民企显著、国企不显著,所以存在异质性”。正确写法必须报告组间差异检验。异质性分析最容易被写成肉眼比较两张表,这一点要避免。
本页案例代码和输出
下面这部分是本教程对应的实际案例材料,方便你把前面的解释和真实输出对上。
Stata 代码
log using "/root/workspace/empirical-wizard/workspace/f3e008aa/analysis.log", replace text
global JOB_DIR "/root/workspace/empirical-wizard/workspace/f3e008aa"
set more off
adopath + "/root/ado/plus"
global DATA_PATH "/root/workspace/empirical-wizard/workspace/test_e2e/csmar_innovation.csv"
import delimited "/root/workspace/empirical-wizard/workspace/test_e2e/csmar_innovation.csv", clear case(preserve)
capture confirm global JOB_DIR
if _rc global JOB_DIR "."
* 自动去除完全重复行(同列同值),避免 N 虚增与 xtset 失败
quietly duplicates drop
local idvar ""
local timevar ""
capture confirm variable stkcd
if !_rc {
capture confirm numeric variable stkcd
if _rc {
tempvar __ewiz_id
capture encode stkcd, gen(`__ewiz_id')
if !_rc local idvar "`__ewiz_id'"
}
else {
local idvar "stkcd"
}
}
else {
di as text "面板ID变量不存在,跳过 xtset ID:stkcd"
}
capture confirm variable year
if !_rc {
capture confirm numeric variable year
if _rc {
tempvar __ewiz_time
capture encode year, gen(`__ewiz_time')
if !_rc local timevar "`__ewiz_time'"
}
else {
local timevar "year"
}
}
else {
di as text "时间变量不存在,跳过 xtset time:year"
}
if "`idvar'" != "" & "`timevar'" != "" {
capture xtset `idvar' `timevar'
}
capture confirm numeric variable size
tempvar __grp_src
if _rc {
encode size, gen(`__grp_src')
}
else {
gen double `__grp_src' = size
}
quietly summarize `__grp_src', detail
local __med = r(p50)
tempvar __grp
gen byte `__grp' = cond(`__grp_src' >= `__med', 1, 0) if !missing(`__grp_src')
levelsof `__grp', local(groups_all)
// 样本充分性护栏:每组至少需要 params+10 观测才跑回归,否则跳过
local _min_n = 27 // params (iv+controls) + safety buffer
local groups ""
foreach g of local groups_all {
quietly count if `__grp'==`g'
if r(N) >= `_min_n' {
local groups "`groups' `g'"
}
else {
di as text "[异质性] 跳过 g=`g',N=" r(N) " < " `_min_n' "(样本不足以承载 FE + 控制变量,会导致 R²=1 过拟合)"
}
}
if "`groups'" == "" {
di as error "[异质性] 所有分组样本均不足,无法执行异质性分析。建议改为 by_median 或 by_terciles 粗分组。"
exit 0
}
tempname fh
capture file close `fh'
file open `fh' using "$JOB_DIR/regression_table_异质性检验.csv", write replace
local __hdr = "变量"
foreach g of local groups {
local __grp_label "(size<中位数)"
if "`g'" == "1" local __grp_label "(size≥中位数)"
local __hdr = "`__hdr',`__grp_label'"
}
file write `fh' "`__hdr'" _n
local __row = "dfi_index"
foreach g of local groups {
capture quietly reghdfe patent_count dfi_index roa lev size growth cashflow tobinq top1 dual board indep soe age if `__grp'==`g', absorb(`timevar' ind) vce(robust) keepsingletons
if _rc==0 {
capture local __c = _b[dfi_index]
capture local __se = _se[dfi_index]
capture local __p = 2*ttail(e(df_r), abs(`__c'/`__se'))
local __stars = cond(`__p'<0.01,"***",cond(`__p'<0.05,"**",cond(`__p'<0.1,"*","")))
local __coef_s : display %9.4f `__c'
capture if abs(`__c') < 0.00005 & `__c' != 0 local __coef_s : display %9.2e `__c'
local __row = "`__row',`__coef_s'`__stars'"
}
else {
local __row = "`__row',"
}
}
file write `fh' "`__row'" _n
local __row = ""
foreach g of local groups {
capture quietly reghdfe patent_count dfi_index roa lev size growth cashflow tobinq top1 dual board indep soe age if `__grp'==`g', absorb(`timevar' ind) vce(robust) keepsingletons
if _rc==0 {
capture local __se = _se[dfi_index]
local __se_s : display %9.4f `__se'
capture if abs(`__se') < 0.00005 & `__se' != 0 local __se_s : display %9.2e `__se'
local __row = "`__row',(`__se_s')"
}
else {
local __row = "`__row',"
}
}
file write `fh' "`__row'" _n
local __row = "roa"
foreach g of local groups {
capture quietly reghdfe patent_count dfi_index roa lev size growth cashflow tobinq top1 dual board indep soe age if `__grp'==`g', absorb(`timevar' ind) vce(robust) keepsingletons
if _rc==0 {
capture local __c = _b[roa]
capture local __se = _se[roa]
capture local __p = 2*ttail(e(df_r), abs(`__c'/`__se'))
local __stars = cond(`__p'<0.01,"***",cond(`__p'<0.05,"**",cond(`__p'<0.1,"*","")))
local __coef_s : display %9.4f `__c'
capture if abs(`__c') < 0.00005 & `__c' != 0 local __coef_s : display %9.2e `__c'
local __row = "`__row',`__coef_s'`__stars'"
}
else {
local __row = "`__row',"
}
}
file write `fh' "`__row'" _n
local __row = ""
foreach g of local groups {
capture quietly reghdfe patent_count dfi_index roa lev size growth cashflow tobinq top1 dual board indep soe age if `__grp'==`g', absorb(`timevar' ind) vce(robust) keepsingletons
if _rc==0 {
capture local __se = _se[roa]
local __se_s : display %9.4f `__se'
capture if abs(`__se') < 0.00005 & `__se' != 0 local __se_s : display %9.2e `__se'
local __row = "`__row',(`__se_s')"
}
else {
local __row = "`__row',"
}
}
file write `fh' "`__row'" _n
local __row = "lev"
foreach g of local groups {
capture quietly reghdfe patent_count dfi_index roa lev size growth cashflow tobinq top1 dual board indep soe age if `__grp'==`g', absorb(`timevar' ind) vce(robust) keepsingletons
if _rc==0 {
capture local __c = _b[lev]
capture local __se = _se[lev]
capture local __p = 2*ttail(e(df_r), abs(`__c'/`__se'))
local __stars = cond(`__p'<0.01,"***",cond(`__p'<0.05,"**",cond(`__p'<0.1,"*","")))
local __coef_s : display %9.4f `__c'
capture if abs(`__c') < 0.00005 & `__c' != 0 local __coef_s : display %9.2e `__c'
local __row = "`__row',`__coef_s'`__stars'"
}
else {
local __row = "`__row',"
}
}
file write `fh' "`__row'" _n
local __row = ""
foreach g of local groups {
capture quietly reghdfe patent_count dfi_index roa lev size growth cashflow tobinq top1 dual board indep soe age if `__grp'==`g', absorb(`timevar' ind) vce(robust) keepsingletons
if _rc==0 {
capture local __se = _se[lev]
local __se_s : display %9.4f `__se'
capture if abs(`__se') < 0.00005 & `__se' != 0 local __se_s : display %9.2e `__se'
local __row = "`__row',(`__se_s')"
}
else {
local __row = "`__row',"
}
}
file write `fh' "`__row'" _n
local __row = "size"
foreach g of local groups {
capture quietly reghdfe patent_count dfi_index roa lev size growth cashflow tobinq top1 dual board indep soe age if `__grp'==`g', absorb(`timevar' ind) vce(robust) keepsingletons
if _rc==0 {
capture local __c = _b[size]
capture local __se = _se[size]
capture local __p = 2*ttail(e(df_r), abs(`__c'/`__se'))
local __stars = cond(`__p'<0.01,"***",cond(`__p'<0.05,"**",cond(`__p'<0.1,"*","")))
local __coef_s : display %9.4f `__c'
capture if abs(`__c') < 0.00005 & `__c' != 0 local __coef_s : display %9.2e `__c'
local __row = "`__row',`__coef_s'`__stars'"
}
else {
local __row = "`__row',"
}
}
file write `fh' "`__row'" _n
local __row = ""
foreach g of local groups {
capture quietly reghdfe patent_count dfi_index roa lev size growth cashflow tobinq top1 dual board indep soe age if `__grp'==`g', absorb(`timevar' ind) vce(robust) keepsingletons
if _rc==0 {
capture local __se = _se[size]
local __se_s : display %9.4f `__se'
capture if abs(`__se') < 0.00005 & `__se' != 0 local __se_s : display %9.2e `__se'
local __row = "`__row',(`__se_s')"
}
else {
local __row = "`__row',"
}
}
file write `fh' "`__row'" _n
local __row = "growth"
foreach g of local groups {
capture quietly reghdfe patent_count dfi_index roa lev size growth cashflow tobinq top1 dual board indep soe age if `__grp'==`g', absorb(`timevar' ind) vce(robust) keepsingletons
if _rc==0 {
capture local __c = _b[growth]
capture local __se = _se[growth]
capture local __p = 2*ttail(e(df_r), abs(`__c'/`__se'))
local __stars = cond(`__p'<0.01,"***",cond(`__p'<0.05,"**",cond(`__p'<0.1,"*","")))
local __coef_s : display %9.4f `__c'
capture if abs(`__c') < 0.00005 & `__c' != 0 local __coef_s : display %9.2e `__c'
local __row = "`__row',`__coef_s'`__stars'"
}
else {
local __row = "`__row',"
}
}
file write `fh' "`__row'" _n
local __row = ""
foreach g of local groups {
capture quietly reghdfe patent_count dfi_index roa lev size growth cashflow tobinq top1 dual board indep soe age if `__grp'==`g', absorb(`timevar' ind) vce(robust) keepsingletons
if _rc==0 {
capture local __se = _se[growth]
local __se_s : display %9.4f `__se'
capture if abs(`__se') < 0.00005 & `__se' != 0 local __se_s : display %9.2e `__se'
local __row = "`__row',(`__se_s')"
}
else {
local __row = "`__row',"
}
}
file write `fh' "`__row'" _n
local __row = "cashflow"
foreach g of local groups {
capture quietly reghdfe patent_count dfi_index roa lev size growth cashflow tobinq top1 dual board indep soe age if `__grp'==`g', absorb(`timevar' ind) vce(robust) keepsingletons
if _rc==0 {
capture local __c = _b[cashflow]
capture local __se = _se[cashflow]
capture local __p = 2*ttail(e(df_r), abs(`__c'/`__se'))
local __stars = cond(`__p'<0.01,"***",cond(`__p'<0.05,"**",cond(`__p'<0.1,"*","")))
local __coef_s : display %9.4f `__c'
capture if abs(`__c') < 0.00005 & `__c' != 0 local __coef_s : display %9.2e `__c'
local __row = "`__row',`__coef_s'`__stars'"
}
else {
local __row = "`__row',"
}
}
file write `fh' "`__row'" _n
local __row = ""
foreach g of local groups {
capture quietly reghdfe patent_count dfi_index roa lev size growth cashflow tobinq top1 dual board indep soe age if `__grp'==`g', absorb(`timevar' ind) vce(robust) keepsingletons
if _rc==0 {
capture local __se = _se[cashflow]
local __se_s : display %9.4f `__se'
capture if abs(`__se') < 0.00005 & `__se' != 0 local __se_s : display %9.2e `__se'
local __row = "`__row',(`__se_s')"
}
else {
local __row = "`__row',"
}
}
file write `fh' "`__row'" _n
local __row = "tobinq"
foreach g of local groups {
capture quietly reghdfe patent_count dfi_index roa lev size growth cashflow tobinq top1 dual board indep soe age if `__grp'==`g', absorb(`timevar' ind) vce(robust) keepsingletons
if _rc==0 {
capture local __c = _b[tobinq]
capture local __se = _se[tobinq]
capture local __p = 2*ttail(e(df_r), abs(`__c'/`__se'))
local __stars = cond(`__p'<0.01,"***",cond(`__p'<0.05,"**",cond(`__p'<0.1,"*","")))
local __coef_s : display %9.4f `__c'
capture if abs(`__c') < 0.00005 & `__c' != 0 local __coef_s : display %9.2e `__c'
local __row = "`__row',`__coef_s'`__stars'"
}
else {
local __row = "`__row',"
}
}
file write `fh' "`__row'" _n
local __row = ""
foreach g of local groups {
capture quietly reghdfe patent_count dfi_index roa lev size growth cashflow tobinq top1 dual board indep soe age if `__grp'==`g', absorb(`timevar' ind) vce(robust) keepsingletons
if _rc==0 {
capture local __se = _se[tobinq]
local __se_s : display %9.4f `__se'
capture if abs(`__se') < 0.00005 & `__se' != 0 local __se_s : display %9.2e `__se'
local __row = "`__row',(`__se_s')"
}
else {
local __row = "`__row',"
}
}
file write `fh' "`__row'" _n
local __row = "top1"
foreach g of local groups {
capture quietly reghdfe patent_count dfi_index roa lev size growth cashflow tobinq top1 dual board indep soe age if `__grp'==`g', absorb(`timevar' ind) vce(robust) keepsingletons
if _rc==0 {
capture local __c = _b[top1]
capture local __se = _se[top1]
capture local __p = 2*ttail(e(df_r), abs(`__c'/`__se'))
local __stars = cond(`__p'<0.01,"***",cond(`__p'<0.05,"**",cond(`__p'<0.1,"*","")))
local __coef_s : display %9.4f `__c'
capture if abs(`__c') < 0.00005 & `__c' != 0 local __coef_s : display %9.2e `__c'
local __row = "`__row',`__coef_s'`__stars'"
}
else {
local __row = "`__row',"
}
}
file write `fh' "`__row'" _n
local __row = ""
foreach g of local groups {
capture quietly reghdfe patent_count dfi_index roa lev size growth cashflow tobinq top1 dual board indep soe age if `__grp'==`g', absorb(`timevar' ind) vce(robust) keepsingletons
if _rc==0 {
capture local __se = _se[top1]
local __se_s : display %9.4f `__se'
capture if abs(`__se') < 0.00005 & `__se' != 0 local __se_s : display %9.2e `__se'
local __row = "`__row',(`__se_s')"
}
else {
local __row = "`__row',"
}
}
file write `fh' "`__row'" _n
local __row = "dual"
foreach g of local groups {
capture quietly reghdfe patent_count dfi_index roa lev size growth cashflow tobinq top1 dual board indep soe age if `__grp'==`g', absorb(`timevar' ind) vce(robust) keepsingletons
if _rc==0 {
capture local __c = _b[dual]
capture local __se = _se[dual]
capture local __p = 2*ttail(e(df_r), abs(`__c'/`__se'))
local __stars = cond(`__p'<0.01,"***",cond(`__p'<0.05,"**",cond(`__p'<0.1,"*","")))
local __coef_s : display %9.4f `__c'
capture if abs(`__c') < 0.00005 & `__c' != 0 local __coef_s : display %9.2e `__c'
local __row = "`__row',`__coef_s'`__stars'"
}
else {
local __row = "`__row',"
}
}
file write `fh' "`__row'" _n
local __row = ""
foreach g of local groups {
capture quietly reghdfe patent_count dfi_index roa lev size growth cashflow tobinq top1 dual board indep soe age if `__grp'==`g', absorb(`timevar' ind) vce(robust) keepsingletons
if _rc==0 {
capture local __se = _se[dual]
local __se_s : display %9.4f `__se'
capture if abs(`__se') < 0.00005 & `__se' != 0 local __se_s : display %9.2e `__se'
local __row = "`__row',(`__se_s')"
}
else {
local __row = "`__row',"
}
}
file write `fh' "`__row'" _n
local __row = "board"
foreach g of local groups {
capture quietly reghdfe patent_count dfi_index roa lev size growth cashflow tobinq top1 dual board indep soe age if `__grp'==`g', absorb(`timevar' ind) vce(robust) keepsingletons
if _rc==0 {
capture local __c = _b[board]
capture local __se = _se[board]
capture local __p = 2*ttail(e(df_r), abs(`__c'/`__se'))
local __stars = cond(`__p'<0.01,"***",cond(`__p'<0.05,"**",cond(`__p'<0.1,"*","")))
local __coef_s : display %9.4f `__c'
capture if abs(`__c') < 0.00005 & `__c' != 0 local __coef_s : display %9.2e `__c'
local __row = "`__row',`__coef_s'`__stars'"
}
else {
local __row = "`__row',"
}
}
file write `fh' "`__row'" _n
local __row = ""
foreach g of local groups {
capture quietly reghdfe patent_count dfi_index roa lev size growth cashflow tobinq top1 dual board indep soe age if `__grp'==`g', absorb(`timevar' ind) vce(robust) keepsingletons
if _rc==0 {
capture local __se = _se[board]
local __se_s : display %9.4f `__se'
capture if abs(`__se') < 0.00005 & `__se' != 0 local __se_s : display %9.2e `__se'
local __row = "`__row',(`__se_s')"
}
else {
local __row = "`__row',"
}
}
file write `fh' "`__row'" _n
local __row = "indep"
foreach g of local groups {
capture quietly reghdfe patent_count dfi_index roa lev size growth cashflow tobinq top1 dual board indep soe age if `__grp'==`g', absorb(`timevar' ind) vce(robust) keepsingletons
if _rc==0 {
capture local __c = _b[indep]
capture local __se = _se[indep]
capture local __p = 2*ttail(e(df_r), abs(`__c'/`__se'))
local __stars = cond(`__p'<0.01,"***",cond(`__p'<0.05,"**",cond(`__p'<0.1,"*","")))
local __coef_s : display %9.4f `__c'
capture if abs(`__c') < 0.00005 & `__c' != 0 local __coef_s : display %9.2e `__c'
local __row = "`__row',`__coef_s'`__stars'"
}
else {
local __row = "`__row',"
}
}
file write `fh' "`__row'" _n
local __row = ""
foreach g of local groups {
capture quietly reghdfe patent_count dfi_index roa lev size growth cashflow tobinq top1 dual board indep soe age if `__grp'==`g', absorb(`timevar' ind) vce(robust) keepsingletons
if _rc==0 {
capture local __se = _se[indep]
local __se_s : display %9.4f `__se'
capture if abs(`__se') < 0.00005 & `__se' != 0 local __se_s : display %9.2e `__se'
local __row = "`__row',(`__se_s')"
}
else {
local __row = "`__row',"
}
}
file write `fh' "`__row'" _n
local __row = "soe"
foreach g of local groups {
capture quietly reghdfe patent_count dfi_index roa lev size growth cashflow tobinq top1 dual board indep soe age if `__grp'==`g', absorb(`timevar' ind) vce(robust) keepsingletons
if _rc==0 {
capture local __c = _b[soe]
capture local __se = _se[soe]
capture local __p = 2*ttail(e(df_r), abs(`__c'/`__se'))
local __stars = cond(`__p'<0.01,"***",cond(`__p'<0.05,"**",cond(`__p'<0.1,"*","")))
local __coef_s : display %9.4f `__c'
capture if abs(`__c') < 0.00005 & `__c' != 0 local __coef_s : display %9.2e `__c'
local __row = "`__row',`__coef_s'`__stars'"
}
else {
local __row = "`__row',"
}
}
file write `fh' "`__row'" _n
local __row = ""
foreach g of local groups {
capture quietly reghdfe patent_count dfi_index roa lev size growth cashflow tobinq top1 dual board indep soe age if `__grp'==`g', absorb(`timevar' ind) vce(robust) keepsingletons
if _rc==0 {
capture local __se = _se[soe]
local __se_s : display %9.4f `__se'
capture if abs(`__se') < 0.00005 & `__se' != 0 local __se_s : display %9.2e `__se'
local __row = "`__row',(`__se_s')"
}
else {
local __row = "`__row',"
}
}
file write `fh' "`__row'" _n
local __row = "age"
foreach g of local groups {
capture quietly reghdfe patent_count dfi_index roa lev size growth cashflow tobinq top1 dual board indep soe age if `__grp'==`g', absorb(`timevar' ind) vce(robust) keepsingletons
if _rc==0 {
capture local __c = _b[age]
capture local __se = _se[age]
capture local __p = 2*ttail(e(df_r), abs(`__c'/`__se'))
local __stars = cond(`__p'<0.01,"***",cond(`__p'<0.05,"**",cond(`__p'<0.1,"*","")))
local __coef_s : display %9.4f `__c'
capture if abs(`__c') < 0.00005 & `__c' != 0 local __coef_s : display %9.2e `__c'
local __row = "`__row',`__coef_s'`__stars'"
}
else {
local __row = "`__row',"
}
}
file write `fh' "`__row'" _n
local __row = ""
foreach g of local groups {
capture quietly reghdfe patent_count dfi_index roa lev size growth cashflow tobinq top1 dual board indep soe age if `__grp'==`g', absorb(`timevar' ind) vce(robust) keepsingletons
if _rc==0 {
capture local __se = _se[age]
local __se_s : display %9.4f `__se'
capture if abs(`__se') < 0.00005 & `__se' != 0 local __se_s : display %9.2e `__se'
local __row = "`__row',(`__se_s')"
}
else {
local __row = "`__row',"
}
}
file write `fh' "`__row'" _n
local __row = "N"
foreach g of local groups {
capture quietly reghdfe patent_count dfi_index roa lev size growth cashflow tobinq top1 dual board indep soe age if `__grp'==`g', absorb(`timevar' ind) vce(robust) keepsingletons
if _rc==0 {
local __v = e(N)
local __v_s : display %9.0f `__v'
local __row = "`__row',`__v_s'"
}
else {
local __row = "`__row',"
}
}
file write `fh' "`__row'" _n
local __row = "R²"
foreach g of local groups {
capture quietly reghdfe patent_count dfi_index roa lev size growth cashflow tobinq top1 dual board indep soe age if `__grp'==`g', absorb(`timevar' ind) vce(robust) keepsingletons
if _rc==0 {
local __v = e(r2)
local __v_s : display %9.4f `__v'
local __row = "`__row',`__v_s'"
}
else {
local __row = "`__row',"
}
}
file write `fh' "`__row'" _n
file close `fh'
* ── 组间系数差异检验(two-group case)──
* 构造 group × 核心解释变量 交互项,若交互显著则组间差异显著
tempname diff_fh
capture file close `diff_fh'
file open `diff_fh' using "$JOB_DIR/heterogeneity_diff_test.csv", write replace
file write `diff_fh' "项目,值,说明" _n
quietly count if !missing(`__grp')
local _n_total = r(N)
quietly levelsof `__grp', local(_all_g)
local _n_groups : word count `_all_g'
file write `diff_fh' "分组数,`_n_groups',仅二分组情形下 Chow/交互项检验成立" _n
if `_n_groups' == 2 {
tempvar __g_bin __iv_x_g
quietly gen double `__g_bin' = `__grp' - `: word 1 of `_all_g''
quietly replace `__g_bin' = `__g_bin' / (`: word 2 of `_all_g'' - `: word 1 of `_all_g'')
quietly gen double `__iv_x_g' = dfi_index * `__g_bin'
capture reg patent_count dfi_index `__g_bin' `__iv_x_g' roa lev size growth cashflow tobinq top1 dual board indep soe age if !missing(`__grp'), vce(robust)
if _rc == 0 {
local diff_coef = _b[`__iv_x_g']
local diff_se = _se[`__iv_x_g']
local diff_t = `diff_coef' / `diff_se'
* Use t-distribution with regression df_r when available; fall
* back to normal only when df_r is missing. Normal approximation
* over-rejects in small/medium samples.
capture local _diff_df = e(df_r)
if "`_diff_df'" == "" | "`_diff_df'" == "." {
local diff_p = 2*(1 - normal(abs(`diff_t')))
}
else {
local diff_p = 2*ttail(`_diff_df', abs(`diff_t'))
}
local diff_coef_s : display %12.6f `diff_coef'
local diff_se_s : display %12.6f `diff_se'
local diff_p_s : display %9.4f `diff_p'
file write `diff_fh' "组间系数差(组2-组1),`diff_coef_s'," _n
file write `diff_fh' "标准误,`diff_se_s'," _n
file write `diff_fh' "p 值,`diff_p_s',p<0.1 * / p<0.05 ** / p<0.01 ***" _n
if `diff_p' < 0.01 {
file write `diff_fh' "结论,组间差异显著,在 1%% 水平显著" _n
}
else if `diff_p' < 0.05 {
file write `diff_fh' "结论,组间差异显著,在 5%% 水平显著" _n
}
else if `diff_p' < 0.1 {
file write `diff_fh' "结论,组间差异边际显著,在 10%% 水平显著" _n
}
else {
file write `diff_fh' "结论,组间差异不显著,p 值 = `diff_p_s'不能拒绝组间系数相等" _n
}
}
else {
file write `diff_fh' "结论,交互项回归失败," _n
}
}
else if `_n_groups' >= 3 & `_n_groups' <= 6 {
* ── >2 组:suest 多组系数联合相等检验 ──
* 对每个 group 单独估计同一规格,suest 合并方差矩阵后做
* H0: [g1] iv = [g2] iv = ... = [gk] iv 的 Wald 检验。
local __suest_ok = 1
local __est_names ""
local __test_eq ""
local __i = 0
foreach _gv of local _all_g {
local __i = `__i' + 1
capture noisily {
quietly reg patent_count dfi_index roa lev size growth cashflow tobinq top1 dual board indep soe age if `__grp' == `_gv', vce(robust)
}
if _rc != 0 {
local __suest_ok = 0
}
else {
estimates store __het`__i'
local __est_names "`__est_names' __het`__i'"
if `__i' == 1 {
local __test_eq "[__het`__i'_mean]dfi_index"
}
else {
local __test_eq "`__test_eq' = [__het`__i'_mean]dfi_index"
}
}
}
if `__suest_ok' == 1 {
capture noisily suest `__est_names', vce(robust)
if _rc == 0 {
capture noisily test `__test_eq'
if _rc == 0 {
local joint_chi2 = r(chi2)
local joint_df = r(df)
local joint_p = r(p)
local joint_chi2_s : display %9.4f `joint_chi2'
local joint_df_s : display %2.0f `joint_df'
local joint_p_s : display %9.4f `joint_p'
file write `diff_fh' "Wald chi2,`joint_chi2_s',suest 联合检验" _n
file write `diff_fh' "df,`joint_df_s'," _n
file write `diff_fh' "p 值,`joint_p_s'," _n
if `joint_p' < 0.01 file write `diff_fh' "结论,各组系数显著不等,1% 水平拒绝同质" _n
else if `joint_p' < 0.05 file write `diff_fh' "结论,各组系数显著不等,5% 水平拒绝同质" _n
else if `joint_p' < 0.1 file write `diff_fh' "结论,各组系数边际不等,10% 水平拒绝同质" _n
else file write `diff_fh' "结论,各组系数同质性未被拒绝,p=`joint_p_s'" _n
}
else {
file write `diff_fh' "结论,suest test 失败,可能是估计向量不可比" _n
}
}
else {
file write `diff_fh' "结论,suest 合并方差矩阵失败," _n
}
}
else {
file write `diff_fh' "结论,部分子组回归失败 — 无法做 suest 联合检验," _n
}
foreach _en of local __est_names {
capture estimates drop `_en'
}
}
else {
file write `diff_fh' "结论,分组数过多 (>6) — 跳过 suest,建议改为子样本回归," _n
}
file close `diff_fh'
* ── 扩展异质性候选矩阵(exploratory disclosure matrix)──
* 目的:记录候选分组变量的组间差异检验结果;不把显著项自动包装为预设主结论。
tempname cm_fh
capture file close `cm_fh'
file open `cm_fh' using "$JOB_DIR/heterogeneity_candidate_matrix.csv", write replace
file write `cm_fh' "candidate,method,source_groups,n_group0,n_group1,diff_coef,diff_se,diff_p,status,note" _n
* candidate grouping: size
capture confirm variable size
if _rc {
file write `cm_fh' "size,auto_binary_or_median,.,.,.,.,.,.,missing_variable,候选变量不存在" _n
}
else {
tempvar __cm_src __cm_grp __cm_gbin __cm_xg __cm_tag
capture confirm numeric variable size
if _rc {
capture encode size, gen(`__cm_src')
}
else {
capture gen double `__cm_src' = size
}
if _rc {
file write `cm_fh' "size,auto_binary_or_median,.,.,.,.,.,.,encoding_failed,变量无法数值化" _n
}
else {
quietly egen byte `__cm_tag' = tag(`__cm_src') if !missing(`__cm_src')
quietly count if `__cm_tag' == 1
local __cm_ng = r(N)
if `__cm_ng' < 2 {
file write `cm_fh' "size,auto_binary_or_median,`__cm_ng',.,.,.,.,.,degenerate,有效分组少于2组" _n
}
else {
if `__cm_ng' == 2 {
quietly levelsof `__cm_src' if !missing(`__cm_src'), local(__cm_lvls)
quietly gen double `__cm_grp' = `__cm_src'
local __cm_method "binary_or_two_value"
}
else {
quietly summarize `__cm_src' if !missing(`__cm_src'), detail
local __cm_med = r(p50)
quietly gen byte `__cm_grp' = (`__cm_src' >= `__cm_med') if !missing(`__cm_src')
local __cm_method "median_split"
}
quietly levelsof `__cm_grp' if !missing(`__cm_grp'), local(__cm_glvls)
local __cm_gg : word count `__cm_glvls'
if `__cm_gg' != 2 {
file write `cm_fh' "size,auto_binary_or_median,`__cm_ng',.,.,.,.,.,degenerate,二分后仍不是2组" _n
}
else {
local __cm_g0 : word 1 of `__cm_glvls'
local __cm_g1 : word 2 of `__cm_glvls'
quietly count if `__cm_grp'==`__cm_g0'
local __cm_n0 = r(N)
quietly count if `__cm_grp'==`__cm_g1'
local __cm_n1 = r(N)
quietly gen double `__cm_gbin' = (`__cm_grp' == `__cm_g1') if !missing(`__cm_grp')
quietly gen double `__cm_xg' = dfi_index * `__cm_gbin'
capture reg patent_count dfi_index `__cm_gbin' `__cm_xg' roa lev growth cashflow tobinq top1 dual board indep soe age if !missing(`__cm_grp'), vce(robust)
if _rc == 0 {
local __cm_diff = _b[`__cm_xg']
local __cm_se = _se[`__cm_xg']
local __cm_t = `__cm_diff' / `__cm_se'
capture local __cm_df = e(df_r)
local __cm_p = cond("`__cm_df'"=="" | "`__cm_df'"==".", 2*(1-normal(abs(`__cm_t'))), 2*ttail(`__cm_df', abs(`__cm_t')))
local __cm_diff_s : display %12.6f `__cm_diff'
local __cm_se_s : display %12.6f `__cm_se'
local __cm_p_s : display %9.4f `__cm_p'
local __cm_status "not_supported"
if `__cm_p' < 0.1 local __cm_status "supported"
file write `cm_fh' "size,`__cm_method',`__cm_ng',`__cm_n0',`__cm_n1',`__cm_diff_s',`__cm_se_s',`__cm_p_s',`__cm_status',exploratory disclosed candidate" _n
}
else {
file write `cm_fh' "size,auto_binary_or_median,`__cm_ng',`__cm_n0',`__cm_n1',.,.,.,regression_failed,交互项回归失败" _n
}
}
}
}
}
* candidate grouping: age
capture confirm variable age
if _rc {
file write `cm_fh' "age,auto_binary_or_median,.,.,.,.,.,.,missing_variable,候选变量不存在" _n
}
else {
tempvar __cm_src __cm_grp __cm_gbin __cm_xg __cm_tag
capture confirm numeric variable age
if _rc {
capture encode age, gen(`__cm_src')
}
else {
capture gen double `__cm_src' = age
}
if _rc {
file write `cm_fh' "age,auto_binary_or_median,.,.,.,.,.,.,encoding_failed,变量无法数值化" _n
}
else {
quietly egen byte `__cm_tag' = tag(`__cm_src') if !missing(`__cm_src')
quietly count if `__cm_tag' == 1
local __cm_ng = r(N)
if `__cm_ng' < 2 {
file write `cm_fh' "age,auto_binary_or_median,`__cm_ng',.,.,.,.,.,degenerate,有效分组少于2组" _n
}
else {
if `__cm_ng' == 2 {
quietly levelsof `__cm_src' if !missing(`__cm_src'), local(__cm_lvls)
quietly gen double `__cm_grp' = `__cm_src'
local __cm_method "binary_or_two_value"
}
else {
quietly summarize `__cm_src' if !missing(`__cm_src'), detail
local __cm_med = r(p50)
quietly gen byte `__cm_grp' = (`__cm_src' >= `__cm_med') if !missing(`__cm_src')
local __cm_method "median_split"
}
quietly levelsof `__cm_grp' if !missing(`__cm_grp'), local(__cm_glvls)
local __cm_gg : word count `__cm_glvls'
if `__cm_gg' != 2 {
file write `cm_fh' "age,auto_binary_or_median,`__cm_ng',.,.,.,.,.,degenerate,二分后仍不是2组" _n
}
else {
local __cm_g0 : word 1 of `__cm_glvls'
local __cm_g1 : word 2 of `__cm_glvls'
quietly count if `__cm_grp'==`__cm_g0'
local __cm_n0 = r(N)
quietly count if `__cm_grp'==`__cm_g1'
local __cm_n1 = r(N)
quietly gen double `__cm_gbin' = (`__cm_grp' == `__cm_g1') if !missing(`__cm_grp')
quietly gen double `__cm_xg' = dfi_index * `__cm_gbin'
capture reg patent_count dfi_index `__cm_gbin' `__cm_xg' roa lev size growth cashflow tobinq top1 dual board indep soe if !missing(`__cm_grp'), vce(robust)
if _rc == 0 {
local __cm_diff = _b[`__cm_xg']
local __cm_se = _se[`__cm_xg']
local __cm_t = `__cm_diff' / `__cm_se'
capture local __cm_df = e(df_r)
local __cm_p = cond("`__cm_df'"=="" | "`__cm_df'"==".", 2*(1-normal(abs(`__cm_t'))), 2*ttail(`__cm_df', abs(`__cm_t')))
local __cm_diff_s : display %12.6f `__cm_diff'
local __cm_se_s : display %12.6f `__cm_se'
local __cm_p_s : display %9.4f `__cm_p'
local __cm_status "not_supported"
if `__cm_p' < 0.1 local __cm_status "supported"
file write `cm_fh' "age,`__cm_method',`__cm_ng',`__cm_n0',`__cm_n1',`__cm_diff_s',`__cm_se_s',`__cm_p_s',`__cm_status',exploratory disclosed candidate" _n
}
else {
file write `cm_fh' "age,auto_binary_or_median,`__cm_ng',`__cm_n0',`__cm_n1',.,.,.,regression_failed,交互项回归失败" _n
}
}
}
}
}
* candidate grouping: indep
capture confirm variable indep
if _rc {
file write `cm_fh' "indep,auto_binary_or_median,.,.,.,.,.,.,missing_variable,候选变量不存在" _n
}
else {
tempvar __cm_src __cm_grp __cm_gbin __cm_xg __cm_tag
capture confirm numeric variable indep
if _rc {
capture encode indep, gen(`__cm_src')
}
else {
capture gen double `__cm_src' = indep
}
if _rc {
file write `cm_fh' "indep,auto_binary_or_median,.,.,.,.,.,.,encoding_failed,变量无法数值化" _n
}
else {
quietly egen byte `__cm_tag' = tag(`__cm_src') if !missing(`__cm_src')
quietly count if `__cm_tag' == 1
local __cm_ng = r(N)
if `__cm_ng' < 2 {
file write `cm_fh' "indep,auto_binary_or_median,`__cm_ng',.,.,.,.,.,degenerate,有效分组少于2组" _n
}
else {
if `__cm_ng' == 2 {
quietly levelsof `__cm_src' if !missing(`__cm_src'), local(__cm_lvls)
quietly gen double `__cm_grp' = `__cm_src'
local __cm_method "binary_or_two_value"
}
else {
quietly summarize `__cm_src' if !missing(`__cm_src'), detail
local __cm_med = r(p50)
quietly gen byte `__cm_grp' = (`__cm_src' >= `__cm_med') if !missing(`__cm_src')
local __cm_method "median_split"
}
quietly levelsof `__cm_grp' if !missing(`__cm_grp'), local(__cm_glvls)
local __cm_gg : word count `__cm_glvls'
if `__cm_gg' != 2 {
file write `cm_fh' "indep,auto_binary_or_median,`__cm_ng',.,.,.,.,.,degenerate,二分后仍不是2组" _n
}
else {
local __cm_g0 : word 1 of `__cm_glvls'
local __cm_g1 : word 2 of `__cm_glvls'
quietly count if `__cm_grp'==`__cm_g0'
local __cm_n0 = r(N)
quietly count if `__cm_grp'==`__cm_g1'
local __cm_n1 = r(N)
quietly gen double `__cm_gbin' = (`__cm_grp' == `__cm_g1') if !missing(`__cm_grp')
quietly gen double `__cm_xg' = dfi_index * `__cm_gbin'
capture reg patent_count dfi_index `__cm_gbin' `__cm_xg' roa lev size growth cashflow tobinq top1 dual board soe age if !missing(`__cm_grp'), vce(robust)
if _rc == 0 {
local __cm_diff = _b[`__cm_xg']
local __cm_se = _se[`__cm_xg']
local __cm_t = `__cm_diff' / `__cm_se'
capture local __cm_df = e(df_r)
local __cm_p = cond("`__cm_df'"=="" | "`__cm_df'"==".", 2*(1-normal(abs(`__cm_t'))), 2*ttail(`__cm_df', abs(`__cm_t')))
local __cm_diff_s : display %12.6f `__cm_diff'
local __cm_se_s : display %12.6f `__cm_se'
local __cm_p_s : display %9.4f `__cm_p'
local __cm_status "not_supported"
if `__cm_p' < 0.1 local __cm_status "supported"
file write `cm_fh' "indep,`__cm_method',`__cm_ng',`__cm_n0',`__cm_n1',`__cm_diff_s',`__cm_se_s',`__cm_p_s',`__cm_status',exploratory disclosed candidate" _n
}
else {
file write `cm_fh' "indep,auto_binary_or_median,`__cm_ng',`__cm_n0',`__cm_n1',.,.,.,regression_failed,交互项回归失败" _n
}
}
}
}
}
* candidate grouping: ind
capture confirm variable ind
if _rc {
file write `cm_fh' "ind,auto_binary_or_median,.,.,.,.,.,.,missing_variable,候选变量不存在" _n
}
else {
tempvar __cm_src __cm_grp __cm_gbin __cm_xg __cm_tag
capture confirm numeric variable ind
if _rc {
capture encode ind, gen(`__cm_src')
}
else {
capture gen double `__cm_src' = ind
}
if _rc {
file write `cm_fh' "ind,auto_binary_or_median,.,.,.,.,.,.,encoding_failed,变量无法数值化" _n
}
else {
quietly egen byte `__cm_tag' = tag(`__cm_src') if !missing(`__cm_src')
quietly count if `__cm_tag' == 1
local __cm_ng = r(N)
if `__cm_ng' < 2 {
file write `cm_fh' "ind,auto_binary_or_median,`__cm_ng',.,.,.,.,.,degenerate,有效分组少于2组" _n
}
else {
if `__cm_ng' == 2 {
quietly levelsof `__cm_src' if !missing(`__cm_src'), local(__cm_lvls)
quietly gen double `__cm_grp' = `__cm_src'
local __cm_method "binary_or_two_value"
}
else {
quietly summarize `__cm_src' if !missing(`__cm_src'), detail
local __cm_med = r(p50)
quietly gen byte `__cm_grp' = (`__cm_src' >= `__cm_med') if !missing(`__cm_src')
local __cm_method "median_split"
}
quietly levelsof `__cm_grp' if !missing(`__cm_grp'), local(__cm_glvls)
local __cm_gg : word count `__cm_glvls'
if `__cm_gg' != 2 {
file write `cm_fh' "ind,auto_binary_or_median,`__cm_ng',.,.,.,.,.,degenerate,二分后仍不是2组" _n
}
else {
local __cm_g0 : word 1 of `__cm_glvls'
local __cm_g1 : word 2 of `__cm_glvls'
quietly count if `__cm_grp'==`__cm_g0'
local __cm_n0 = r(N)
quietly count if `__cm_grp'==`__cm_g1'
local __cm_n1 = r(N)
quietly gen double `__cm_gbin' = (`__cm_grp' == `__cm_g1') if !missing(`__cm_grp')
quietly gen double `__cm_xg' = dfi_index * `__cm_gbin'
capture reg patent_count dfi_index `__cm_gbin' `__cm_xg' roa lev size growth cashflow tobinq top1 dual board indep soe age if !missing(`__cm_grp'), vce(robust)
if _rc == 0 {
local __cm_diff = _b[`__cm_xg']
local __cm_se = _se[`__cm_xg']
local __cm_t = `__cm_diff' / `__cm_se'
capture local __cm_df = e(df_r)
local __cm_p = cond("`__cm_df'"=="" | "`__cm_df'"==".", 2*(1-normal(abs(`__cm_t'))), 2*ttail(`__cm_df', abs(`__cm_t')))
local __cm_diff_s : display %12.6f `__cm_diff'
local __cm_se_s : display %12.6f `__cm_se'
local __cm_p_s : display %9.4f `__cm_p'
local __cm_status "not_supported"
if `__cm_p' < 0.1 local __cm_status "supported"
file write `cm_fh' "ind,`__cm_method',`__cm_ng',`__cm_n0',`__cm_n1',`__cm_diff_s',`__cm_se_s',`__cm_p_s',`__cm_status',exploratory disclosed candidate" _n
}
else {
file write `cm_fh' "ind,auto_binary_or_median,`__cm_ng',`__cm_n0',`__cm_n1',.,.,.,regression_failed,交互项回归失败" _n
}
}
}
}
}
* candidate grouping: board
capture confirm variable board
if _rc {
file write `cm_fh' "board,auto_binary_or_median,.,.,.,.,.,.,missing_variable,候选变量不存在" _n
}
else {
tempvar __cm_src __cm_grp __cm_gbin __cm_xg __cm_tag
capture confirm numeric variable board
if _rc {
capture encode board, gen(`__cm_src')
}
else {
capture gen double `__cm_src' = board
}
if _rc {
file write `cm_fh' "board,auto_binary_or_median,.,.,.,.,.,.,encoding_failed,变量无法数值化" _n
}
else {
quietly egen byte `__cm_tag' = tag(`__cm_src') if !missing(`__cm_src')
quietly count if `__cm_tag' == 1
local __cm_ng = r(N)
if `__cm_ng' < 2 {
file write `cm_fh' "board,auto_binary_or_median,`__cm_ng',.,.,.,.,.,degenerate,有效分组少于2组" _n
}
else {
if `__cm_ng' == 2 {
quietly levelsof `__cm_src' if !missing(`__cm_src'), local(__cm_lvls)
quietly gen double `__cm_grp' = `__cm_src'
local __cm_method "binary_or_two_value"
}
else {
quietly summarize `__cm_src' if !missing(`__cm_src'), detail
local __cm_med = r(p50)
quietly gen byte `__cm_grp' = (`__cm_src' >= `__cm_med') if !missing(`__cm_src')
local __cm_method "median_split"
}
quietly levelsof `__cm_grp' if !missing(`__cm_grp'), local(__cm_glvls)
local __cm_gg : word count `__cm_glvls'
if `__cm_gg' != 2 {
file write `cm_fh' "board,auto_binary_or_median,`__cm_ng',.,.,.,.,.,degenerate,二分后仍不是2组" _n
}
else {
local __cm_g0 : word 1 of `__cm_glvls'
local __cm_g1 : word 2 of `__cm_glvls'
quietly count if `__cm_grp'==`__cm_g0'
local __cm_n0 = r(N)
quietly count if `__cm_grp'==`__cm_g1'
local __cm_n1 = r(N)
quietly gen double `__cm_gbin' = (`__cm_grp' == `__cm_g1') if !missing(`__cm_grp')
quietly gen double `__cm_xg' = dfi_index * `__cm_gbin'
capture reg patent_count dfi_index `__cm_gbin' `__cm_xg' roa lev size growth cashflow tobinq top1 dual indep soe age if !missing(`__cm_grp'), vce(robust)
if _rc == 0 {
local __cm_diff = _b[`__cm_xg']
local __cm_se = _se[`__cm_xg']
local __cm_t = `__cm_diff' / `__cm_se'
capture local __cm_df = e(df_r)
local __cm_p = cond("`__cm_df'"=="" | "`__cm_df'"==".", 2*(1-normal(abs(`__cm_t'))), 2*ttail(`__cm_df', abs(`__cm_t')))
local __cm_diff_s : display %12.6f `__cm_diff'
local __cm_se_s : display %12.6f `__cm_se'
local __cm_p_s : display %9.4f `__cm_p'
local __cm_status "not_supported"
if `__cm_p' < 0.1 local __cm_status "supported"
file write `cm_fh' "board,`__cm_method',`__cm_ng',`__cm_n0',`__cm_n1',`__cm_diff_s',`__cm_se_s',`__cm_p_s',`__cm_status',exploratory disclosed candidate" _n
}
else {
file write `cm_fh' "board,auto_binary_or_median,`__cm_ng',`__cm_n0',`__cm_n1',.,.,.,regression_failed,交互项回归失败" _n
}
}
}
}
}
* candidate grouping: cashflow
capture confirm variable cashflow
if _rc {
file write `cm_fh' "cashflow,auto_binary_or_median,.,.,.,.,.,.,missing_variable,候选变量不存在" _n
}
else {
tempvar __cm_src __cm_grp __cm_gbin __cm_xg __cm_tag
capture confirm numeric variable cashflow
if _rc {
capture encode cashflow, gen(`__cm_src')
}
else {
capture gen double `__cm_src' = cashflow
}
if _rc {
file write `cm_fh' "cashflow,auto_binary_or_median,.,.,.,.,.,.,encoding_failed,变量无法数值化" _n
}
else {
quietly egen byte `__cm_tag' = tag(`__cm_src') if !missing(`__cm_src')
quietly count if `__cm_tag' == 1
local __cm_ng = r(N)
if `__cm_ng' < 2 {
file write `cm_fh' "cashflow,auto_binary_or_median,`__cm_ng',.,.,.,.,.,degenerate,有效分组少于2组" _n
}
else {
if `__cm_ng' == 2 {
quietly levelsof `__cm_src' if !missing(`__cm_src'), local(__cm_lvls)
quietly gen double `__cm_grp' = `__cm_src'
local __cm_method "binary_or_two_value"
}
else {
quietly summarize `__cm_src' if !missing(`__cm_src'), detail
local __cm_med = r(p50)
quietly gen byte `__cm_grp' = (`__cm_src' >= `__cm_med') if !missing(`__cm_src')
local __cm_method "median_split"
}
quietly levelsof `__cm_grp' if !missing(`__cm_grp'), local(__cm_glvls)
local __cm_gg : word count `__cm_glvls'
if `__cm_gg' != 2 {
file write `cm_fh' "cashflow,auto_binary_or_median,`__cm_ng',.,.,.,.,.,degenerate,二分后仍不是2组" _n
}
else {
local __cm_g0 : word 1 of `__cm_glvls'
local __cm_g1 : word 2 of `__cm_glvls'
quietly count if `__cm_grp'==`__cm_g0'
local __cm_n0 = r(N)
quietly count if `__cm_grp'==`__cm_g1'
local __cm_n1 = r(N)
quietly gen double `__cm_gbin' = (`__cm_grp' == `__cm_g1') if !missing(`__cm_grp')
quietly gen double `__cm_xg' = dfi_index * `__cm_gbin'
capture reg patent_count dfi_index `__cm_gbin' `__cm_xg' roa lev size growth tobinq top1 dual board indep soe age if !missing(`__cm_grp'), vce(robust)
if _rc == 0 {
local __cm_diff = _b[`__cm_xg']
local __cm_se = _se[`__cm_xg']
local __cm_t = `__cm_diff' / `__cm_se'
capture local __cm_df = e(df_r)
local __cm_p = cond("`__cm_df'"=="" | "`__cm_df'"==".", 2*(1-normal(abs(`__cm_t'))), 2*ttail(`__cm_df', abs(`__cm_t')))
local __cm_diff_s : display %12.6f `__cm_diff'
local __cm_se_s : display %12.6f `__cm_se'
local __cm_p_s : display %9.4f `__cm_p'
local __cm_status "not_supported"
if `__cm_p' < 0.1 local __cm_status "supported"
file write `cm_fh' "cashflow,`__cm_method',`__cm_ng',`__cm_n0',`__cm_n1',`__cm_diff_s',`__cm_se_s',`__cm_p_s',`__cm_status',exploratory disclosed candidate" _n
}
else {
file write `cm_fh' "cashflow,auto_binary_or_median,`__cm_ng',`__cm_n0',`__cm_n1',.,.,.,regression_failed,交互项回归失败" _n
}
}
}
}
}
* candidate grouping: dual
capture confirm variable dual
if _rc {
file write `cm_fh' "dual,auto_binary_or_median,.,.,.,.,.,.,missing_variable,候选变量不存在" _n
}
else {
tempvar __cm_src __cm_grp __cm_gbin __cm_xg __cm_tag
capture confirm numeric variable dual
if _rc {
capture encode dual, gen(`__cm_src')
}
else {
capture gen double `__cm_src' = dual
}
if _rc {
file write `cm_fh' "dual,auto_binary_or_median,.,.,.,.,.,.,encoding_failed,变量无法数值化" _n
}
else {
quietly egen byte `__cm_tag' = tag(`__cm_src') if !missing(`__cm_src')
quietly count if `__cm_tag' == 1
local __cm_ng = r(N)
if `__cm_ng' < 2 {
file write `cm_fh' "dual,auto_binary_or_median,`__cm_ng',.,.,.,.,.,degenerate,有效分组少于2组" _n
}
else {
if `__cm_ng' == 2 {
quietly levelsof `__cm_src' if !missing(`__cm_src'), local(__cm_lvls)
quietly gen double `__cm_grp' = `__cm_src'
local __cm_method "binary_or_two_value"
}
else {
quietly summarize `__cm_src' if !missing(`__cm_src'), detail
local __cm_med = r(p50)
quietly gen byte `__cm_grp' = (`__cm_src' >= `__cm_med') if !missing(`__cm_src')
local __cm_method "median_split"
}
quietly levelsof `__cm_grp' if !missing(`__cm_grp'), local(__cm_glvls)
local __cm_gg : word count `__cm_glvls'
if `__cm_gg' != 2 {
file write `cm_fh' "dual,auto_binary_or_median,`__cm_ng',.,.,.,.,.,degenerate,二分后仍不是2组" _n
}
else {
local __cm_g0 : word 1 of `__cm_glvls'
local __cm_g1 : word 2 of `__cm_glvls'
quietly count if `__cm_grp'==`__cm_g0'
local __cm_n0 = r(N)
quietly count if `__cm_grp'==`__cm_g1'
local __cm_n1 = r(N)
quietly gen double `__cm_gbin' = (`__cm_grp' == `__cm_g1') if !missing(`__cm_grp')
quietly gen double `__cm_xg' = dfi_index * `__cm_gbin'
capture reg patent_count dfi_index `__cm_gbin' `__cm_xg' roa lev size growth cashflow tobinq top1 board indep soe age if !missing(`__cm_grp'), vce(robust)
if _rc == 0 {
local __cm_diff = _b[`__cm_xg']
local __cm_se = _se[`__cm_xg']
local __cm_t = `__cm_diff' / `__cm_se'
capture local __cm_df = e(df_r)
local __cm_p = cond("`__cm_df'"=="" | "`__cm_df'"==".", 2*(1-normal(abs(`__cm_t'))), 2*ttail(`__cm_df', abs(`__cm_t')))
local __cm_diff_s : display %12.6f `__cm_diff'
local __cm_se_s : display %12.6f `__cm_se'
local __cm_p_s : display %9.4f `__cm_p'
local __cm_status "not_supported"
if `__cm_p' < 0.1 local __cm_status "supported"
file write `cm_fh' "dual,`__cm_method',`__cm_ng',`__cm_n0',`__cm_n1',`__cm_diff_s',`__cm_se_s',`__cm_p_s',`__cm_status',exploratory disclosed candidate" _n
}
else {
file write `cm_fh' "dual,auto_binary_or_median,`__cm_ng',`__cm_n0',`__cm_n1',.,.,.,regression_failed,交互项回归失败" _n
}
}
}
}
}
* candidate grouping: growth
capture confirm variable growth
if _rc {
file write `cm_fh' "growth,auto_binary_or_median,.,.,.,.,.,.,missing_variable,候选变量不存在" _n
}
else {
tempvar __cm_src __cm_grp __cm_gbin __cm_xg __cm_tag
capture confirm numeric variable growth
if _rc {
capture encode growth, gen(`__cm_src')
}
else {
capture gen double `__cm_src' = growth
}
if _rc {
file write `cm_fh' "growth,auto_binary_or_median,.,.,.,.,.,.,encoding_failed,变量无法数值化" _n
}
else {
quietly egen byte `__cm_tag' = tag(`__cm_src') if !missing(`__cm_src')
quietly count if `__cm_tag' == 1
local __cm_ng = r(N)
if `__cm_ng' < 2 {
file write `cm_fh' "growth,auto_binary_or_median,`__cm_ng',.,.,.,.,.,degenerate,有效分组少于2组" _n
}
else {
if `__cm_ng' == 2 {
quietly levelsof `__cm_src' if !missing(`__cm_src'), local(__cm_lvls)
quietly gen double `__cm_grp' = `__cm_src'
local __cm_method "binary_or_two_value"
}
else {
quietly summarize `__cm_src' if !missing(`__cm_src'), detail
local __cm_med = r(p50)
quietly gen byte `__cm_grp' = (`__cm_src' >= `__cm_med') if !missing(`__cm_src')
local __cm_method "median_split"
}
quietly levelsof `__cm_grp' if !missing(`__cm_grp'), local(__cm_glvls)
local __cm_gg : word count `__cm_glvls'
if `__cm_gg' != 2 {
file write `cm_fh' "growth,auto_binary_or_median,`__cm_ng',.,.,.,.,.,degenerate,二分后仍不是2组" _n
}
else {
local __cm_g0 : word 1 of `__cm_glvls'
local __cm_g1 : word 2 of `__cm_glvls'
quietly count if `__cm_grp'==`__cm_g0'
local __cm_n0 = r(N)
quietly count if `__cm_grp'==`__cm_g1'
local __cm_n1 = r(N)
quietly gen double `__cm_gbin' = (`__cm_grp' == `__cm_g1') if !missing(`__cm_grp')
quietly gen double `__cm_xg' = dfi_index * `__cm_gbin'
capture reg patent_count dfi_index `__cm_gbin' `__cm_xg' roa lev size cashflow tobinq top1 dual board indep soe age if !missing(`__cm_grp'), vce(robust)
if _rc == 0 {
local __cm_diff = _b[`__cm_xg']
local __cm_se = _se[`__cm_xg']
local __cm_t = `__cm_diff' / `__cm_se'
capture local __cm_df = e(df_r)
local __cm_p = cond("`__cm_df'"=="" | "`__cm_df'"==".", 2*(1-normal(abs(`__cm_t'))), 2*ttail(`__cm_df', abs(`__cm_t')))
local __cm_diff_s : display %12.6f `__cm_diff'
local __cm_se_s : display %12.6f `__cm_se'
local __cm_p_s : display %9.4f `__cm_p'
local __cm_status "not_supported"
if `__cm_p' < 0.1 local __cm_status "supported"
file write `cm_fh' "growth,`__cm_method',`__cm_ng',`__cm_n0',`__cm_n1',`__cm_diff_s',`__cm_se_s',`__cm_p_s',`__cm_status',exploratory disclosed candidate" _n
}
else {
file write `cm_fh' "growth,auto_binary_or_median,`__cm_ng',`__cm_n0',`__cm_n1',.,.,.,regression_failed,交互项回归失败" _n
}
}
}
}
}
file close `cm_fh'
di "异质性分析完成:分组变量=size,方法=by_median"
log close
输出表
| 项目 | 值 | 说明 |
|---|---|---|
| 分组数 | 2 | 仅二分组情形下 Chow/交互项检验成立 |
| 组间系数差(组2-组1) | -0.000924 | |
| 标准误 | 0.080567 | |
| p 值 | 0.9909 | p<0.1 * / p<0.05 ** / p<0.01 *** |
| 结论 | 组间差异不显著 | p 值 = 0.9909不能拒绝组间系数相等 |
补充输出
下面这些文件来自同一次案例运行或烟测输出,用来补齐主表之外的诊断信息。
heterogeneity_candidate_matrix.csv
| candidate | method | source_groups | n_group0 | n_group1 | diff_coef | diff_se | diff_p | status | note |
|---|---|---|---|---|---|---|---|---|---|
| size | median_split | 713 | 360 | 360 | -0.014187 | 0.081464 | 0.8618 | not_supported | exploratory disclosed candidate |
| age | median_split | 711 | 360 | 360 | 0.080481 | 0.082598 | 0.3302 | not_supported | exploratory disclosed candidate |
| indep | median_split | 711 | 360 | 360 | -0.041161 | 0.083297 | 0.6214 | not_supported | exploratory disclosed candidate |
| ind | median_split | 8 | 360 | 360 | -0.042618 | 0.082585 | 0.6060 | not_supported | exploratory disclosed candidate |
| board | median_split | 716 | 360 | 360 | -0.083428 | 0.084312 | 0.3228 | not_supported | exploratory disclosed candidate |
| cashflow | median_split | 712 | 360 | 360 | 0.027120 | 0.081387 | 0.7391 | not_supported | exploratory disclosed candidate |
| dual | median_split | 715 | 360 | 360 | 0.177181 | 0.081392 | 0.0298 | supported | exploratory disclosed candidate |
| growth | median_split | 715 | 360 | 360 | -0.009234 | 0.081983 | 0.9104 | not_supported | exploratory disclosed candidate |
regression_table_异质性检验.csv
| 变量 | (size<中位数) | (size≥中位数) |
|---|---|---|
| dfi_index | 0.5890*** | 0.5784*** |
| ( 0.0596) | ( 0.0542) | |
| roa | 0.2790*** | 0.3030*** |
| ( 0.0636) | ( 0.0592) | |
| lev | -0.0311 | -0.0202 |
| ( 0.0613) | ( 0.0655) | |
| size | 0.1006 | 0.3969*** |
| ( 0.0855) | ( 0.1092) | |
| growth | 0.0389 | -0.1402** |
| ( 0.0611) | ( 0.0640) | |
| cashflow | 0.0532 | -0.0009 |
| ( 0.0649) | ( 0.0546) | |
| tobinq | 0.0692 | -0.0029 |
| ( 0.0695) | ( 0.0608) | |
| top1 | -0.0406 | 0.0147 |
| ( 0.0633) | ( 0.0638) | |
| dual | -0.0110 | 0.0127 |
| ( 0.0603) | ( 0.0657) | |
| board | -0.0549 | 0.0066 |
| ( 0.0552) | ( 0.0593) | |
| indep | 0.0553 | -0.0808 |
| ( 0.0667) | ( 0.0574) | |
| soe | 0.0379 | -0.0521 |
| ( 0.0602) | ( 0.0681) | |
| age | 0.0449 | -0.0628 |
| ( 0.0606) | ( 0.0569) | |
| N | 360 | 360 |
| R² | 0.2840 | 0.3323 |
案例图

写作检查
本文在共用企业面板样本上报告Chow 已知断点检验,核心输出见 chow_test_results.csv。结果解释时同时关注样本口径、变量构造、系数方向、标准误和适用前提,避免只凭单个 p 值完成方法选择。
- 确认本页使用的因变量、核心解释变量、控制变量与论文主模型一致。
- 先看表格里的样本口径,再看系数、p 值或诊断指标。
- 代码里的输出文件名要能对应网页展示的结果表。