简介:这份资源面向社会科学、经济学等领域的实证研究者与Stata使用者,聚焦面板数据中中介效应与调节效应的操作演示,适合已掌握基础回归、希望进阶处理变量间复杂关系的中级学习者。压缩包共269个文件,约1.26MB,以ado命令文件(96个)、hlp与sthlp帮助文档(134个)为主,另含mata、mlib、dta示例数据及do脚本等,覆盖reghdfe、estout、coefplot、xtabond2等常用外部命令,便于直接调用与查阅。资源围绕中介效应的mediate命令实现、调节效应的交互项构建与结果解读展开,可帮助读者理解自变量通过中介变量影响因变量的传递机制,以及调节变量如何改变变量间关系强度,并掌握系数、标准误与显著性判断的完整流程。目前已有24365人学习下载,适合需要系统练习面板数据效应分析、对照命令与结果解释的研究者参考。
1. 面板数据里做中介和调节,为什么总有人把交互项和中介项搞反
面板数据的中介效应和调节效应,是实证论文里出现频率最高、也最容易被审稿人揪住的两类机制检验。我见过太多稿子,模型跑出来了,系数也显著,但把中介和调节的逻辑讲反了——本该是“X通过M影响Y”的中介链条,硬生生写成了“M调节了X对Y的作用”;本该是“Z改变了X对Y的强度”的调节关系,却塞进了一个中介模型里。这不是统计软件的问题,是研究设计的问题,Stata只是把你的设定忠实执行出来。
这篇笔记面向的是手里已经有面板数据、准备在Stata里跑机制检验的实证研究者。不管你是刚接触面板中介的新手,还是跑过几轮调节但不确定Bootstrap参数怎么设的老手,下面这套流程和踩坑记录都能直接拿去用。核心工具是Stata的sem、gsem、bootstrap和reghdfe,配合medeff、med4way等社区命令。我会把每一步的代码、参数含义、失败时看什么讲清楚,不绕弯子。
2. 中介效应和调节效应在面板设定下的模型差异
2.1 中介效应的三条路径与面板固定效应的冲突
中介效应的经典框架是Baron-Kenny三步法:X对Y的总效应显著,X对M显著,M对Y显著且X对Y的系数下降。但在面板数据里,这三步法有个致命问题——固定效应会吸收掉不随时间变化的个体异质性,而中介变量M往往恰恰是那些被吸收掉的稳定特征。比如研究“数字化转型→创新能力→企业绩效”,创新能力如果短期内变化很小,固定效应一加,M的组内变异所剩无几,中介路径直接跑不出显著。
常见做法是改用gsem做路径分析,同时用bootstrap估计间接效应的置信区间。Stata 17以后gsem支持面板结构,可以指定xtset后的面板变量,用method(ml)做极大似然估计。但要注意,gsem的面板中介默认不包含个体固定效应,需要手动加入i.id或者用xtreg的组内变换预处理。
* 面板中介效应:gsem + bootstrap * 假设已 xtset id year * 模型:X -> M -> Y,控制变量 cv1 cv2 capture program drop panel_mediation program define panel_mediation, rclass gsem (M <- X cv1 cv2 i.id) (Y <- M X cv1 cv2 i.id), /// var(M) var(Y) method(ml) return scalar indir = _b[M:X] * _b[Y:M] return scalar dir = _b[Y:X] end bootstrap r(indir) r(dir), reps(500) seed(12345) cluster(id): panel_mediation estat bootstrap, all这段代码的逻辑是:用gsem同时估计M方程和Y方程,间接效应等于X→M的系数乘以M→Y的系数。bootstrap重抽样500次,cluster(id)按个体聚类,避免面板数据里的序列相关导致标准误低估。seed固定随机种子保证可复现。跑完后estat bootstrap会给出偏差校正的置信区间,如果区间不包含0,间接效应成立。
参数上,reps(500)是经验值,一般不少于500,条件允许跑1000更稳。cluster(id)必须加,否则面板数据的标准误会偏小,间接效应容易假显著。method(ml)是默认的极大似然,如果模型复杂跑不动,可以换method(gsem)的默认迭代法。
2.2 调节效应:交互项的中心化与面板固定效应的交互
调节效应的核心是交互项X*Z。在面板数据里,交互项本身不是问题,问题是中心化。很多教程说“必须中心化以避免多重共线性”,但在固定效应模型里,中心化与否不影响交互项系数的解释,只影响主效应的解释。真正要命的是,如果你用xtreg, fe跑交互,Stata会自动把交互项也做组内变换,这时候交互项的系数含义变成了“组内X变化与组内Z变化的交互”,而不是原始变量的交互。
我一般会先用reghdfe跑,因为它对高维固定效应的处理更干净,而且支持absorb多个固定效应。交互项用c.X##c.Z的写法,Stata会自动生成主效应和交互项。
* 面板调节效应:reghdfe + 交互项 * 安装:ssc install reghdfe, replace * ssc install ftools, replace reghdfe Y c.X##c.Z cv1 cv2, absorb(id year) vce(cluster id) * 简单斜率:在Z的均值±1SD处看X的边际效应 margins, dydx(X) at(Z=(-1 0 1)) vsquish marginsplot, xdimension(Z) recast(line) /// ytitle("X对Y的边际效应") xtitle("调节变量Z")absorb(id year)同时吸收个体和年份固定效应,vce(cluster id)聚类稳健标准误。margins命令在Z的-1、0、1三个点(通常是均值减一个标准差、均值、均值加一个标准差)计算X对Y的边际效应,marginsplot画出简单斜率图。如果三条斜率线的差异显著,调节效应成立。
参数上,c.X##c.Z里的c.表示连续变量,如果Z是分类变量,改用i.Z。vsquish压缩输出,recast(line)把点图改成线图。注意margins默认用t分布,面板数据小样本时更稳。
2.3 中介和调节同时存在时的有调节的中介模型
当研究假设是“X通过M影响Y,且这个中介路径受到Z的调节”,就是有调节的中介。Stata里可以用med4way命令,它专门处理这种复杂机制,支持面板数据的聚类标准误。但med4way要求变量命名规范,且对缺失值敏感,跑之前务必misstable summarize检查。
* 有调节的中介:med4way * 安装:ssc install med4way, replace med4way Y M X Z cv1 cv2, /// cvar(cv1 cv2) /// a0(0) a1(1) b0(0) b1(1) /// boot(1000) seed(12345) cluster(id)a0(0) a1(1)指定调节变量Z的取值点,b0(0) b1(1)同理。boot(1000)做1000次Bootstrap。输出会给出不同Z取值下的间接效应和调节中介指数。如果调节中介指数的置信区间不含0,说明中介效应确实被Z调节了。
3. 在Stata里跑通面板中介和调节的完整操作流程
3.1 数据准备与面板设定
第一步永远是xtset。没有这一步,后面所有面板命令都会报错。xtset id year之后,用xtdescribe看面板结构是否平衡,用misstable summarize看缺失模式。如果缺失集中在某些年份或个体,考虑用tsfill补齐时间维度,但不要盲目插补。
* 数据准备 xtset id year xtdescribe misstable summarize Y M X Z cv1 cv2 * 如果缺失严重,检查是否需要用 mi 或 ipolate * 生成中心化变量(调节效应用) center X Z cv1 cv2, prefix(c_) * 生成交互项 gen c_XZ = c_X * c_Zcenter是社区命令,ssc install center安装。中心化后生成交互项,避免手动计算出错。注意,如果后面用reghdfe的c.X##c.Z写法,其实不需要手动生成交互项,Stata会自动处理。手动生成的好处是可以在gsem里直接引用。
3.2 中介效应的Bootstrap实现与结果解读
回到2.1的panel_mediation程序。跑完后重点看三件事:间接效应的Bootstrap置信区间、直接效应的显著性、总效应是否等于直接加间接。如果间接效应显著但直接效应也显著,是部分中介;如果直接效应不显著,是完全中介。但面板数据里完全中介很少见,因为固定效应已经吸收了大量变异。
* 跑完bootstrap后提取结果 matrix b = e(b) matrix ci = e(ci_percentile) * 间接效应 di "间接效应 = " b[1,1] di "95%百分位置信区间 = [" ci[1,1] ", " ci[1,2] "]" * 如果区间不含0,中介成立e(ci_percentile)是百分位Bootstrap置信区间,比正态近似更稳健。如果区间下限和上限同号,间接效应显著。注意,Bootstrap的reps越多,区间越稳定,但耗时也越长。500次大概几十秒,1000次翻倍。
3.3 调节效应的简单斜率与交互图
margins和marginsplot是调节效应的标配。但有个坑:如果交互项不显著,不要强行画简单斜率图,审稿人一眼就能看出你在凑图。先看reghdfe输出里c.X#c.Z的系数和p值,显著了再画。
* 调节效应完整流程 reghdfe Y c.X##c.Z cv1 cv2, absorb(id year) vce(cluster id) est store m1 * 如果交互项显著,做简单斜率 margins, dydx(X) at(Z=(-1 0 1)) vsquish marginsplot, xdimension(Z) recast(line) /// ytitle("X对Y的边际效应") xtitle("调节变量Z") /// title("调节效应简单斜率图") /// legend(order(1 "Z=-1SD" 2 "Z=均值" 3 "Z=+1SD")) * 导出图片 graph export "moderation_slope.png", replace width(2000)est store m1保存模型,方便后续对比。marginsplot的legend选项自定义图例,graph export导出高清图。注意,margins默认在Z的均值处计算,at(Z=(-1 0 1))指定三个点,这里的-1和1是标准差单位,不是原始值。
3.4 有调节的中介:med4way的调用与参数设置
med4way的语法比较特殊,需要指定调节变量的取值点。a0(0) a1(1)和b0(0) b1(1)分别对应Z的低值和高值。输出会给出四个间接效应:Z=0时的间接效应、Z=1时的间接效应、以及调节中介指数。如果调节中介指数的置信区间不含0,说明中介效应被调节。
* 有调节的中介 med4way Y M X Z cv1 cv2, /// cvar(cv1 cv2) /// a0(0) a1(1) b0(0) b1(1) /// boot(1000) seed(12345) cluster(id) * 输出解读: * 间接效应(Z=0) = a0*b0 * 间接效应(Z=1) = a1*b1 * 调节中介指数 = (a1*b1 - a0*b0)cvar指定控制变量,boot和seed同前。cluster(id)按个体聚类。如果med4way报错“variable not found”,检查变量名是否拼写正确,以及是否有缺失值。med4way对缺失值零容忍,跑之前用drop if missing(Y,M,X,Z)清理。
4. 面板中介和调节的避坑与排查清单
4.1 坑一:固定效应吃掉中介变量,间接效应不显著
现象:gsem跑出来X→M显著,M→Y也显著,但Bootstrap间接效应置信区间包含0。原因:固定效应吸收了M的组内变异,导致M的系数估计不稳定。解决:先跑xtsum M看组内标准差,如果组内变异小于总变异的10%,考虑改用随机效应模型,或者用xtreg, re配合gsem的method(ml)。另一个办法是把M滞后一期,用L.M作为中介变量,增加时序变异。
4.2 坑二:交互项中心化后主效应解释混乱
现象:中心化后跑reghdfe,X的主效应变得不显著,但交互项显著。原因:中心化后X的主效应含义变成了“Z处于均值时X对Y的效应”,而不是“Z=0时X对Y的效应”。解决:如果Z的0值没有实际意义,中心化是合理的;如果Z的0值有意义(比如政策冲击的0/1变量),不要中心化,直接用原始变量跑交互。判断标准是看Z的0值是否在数据范围内。
4.3 坑三:Bootstrap聚类标准误与面板结构不匹配
现象:bootstrap跑完,间接效应显著,但换成cluster(id)后不显著了。原因:没有聚类时,Bootstrap把每个观测当作独立个体,忽略了面板内的序列相关,标准误被低估。解决:bootstrap里必须加cluster(id),且id要和xtset的面板变量一致。如果id有重复,先用duplicates report id检查。
4.4 坑四:med4way对缺失值和变量类型敏感
现象:med4way报错“conformability error”或“invalid name”。原因:变量名有空格或特殊字符,或者缺失值导致矩阵维度不匹配。解决:用rename把变量名改成纯字母数字,用drop if missing()清理缺失值。如果Z是分类变量,先encode成数值型,再在med4way里用i.Z指定。
4.5 坑五:gsem收敛失败或迭代次数超限
现象:gsem跑一半报错“convergence not achieved”。原因:模型太复杂,或者初始值不合理。解决:先用gsem的technique(nr)换牛顿-拉夫森算法,或者iterate(100)增加迭代次数。如果还不行,简化模型,先跑单独的M方程和Y方程,确认每个方程都能收敛,再合并。
5. 进阶:用Bootstrap做面板中介的置信区间校正与敏感性分析
Bootstrap的百分位置信区间在面板数据里有个隐患:当个体数较少(比如N<50)时,百分位法会低估覆盖概率。我一般会同时报告偏差校正的加速法(BCa)置信区间,用estat bootstrap, all输出。BCa对偏态分布更稳健,但计算量大,reps要跑到2000以上才稳定。
* BCa置信区间 bootstrap r(indir) r(dir), reps(2000) seed(12345) cluster(id): panel_mediation estat bootstrap, all * 输出包含: * - Normal-based * - Percentile * - Bias-corrected * - Bias-corrected and accelerated (BCa)如果BCa和百分位区间结论一致,中介效应基本可信。如果不一致,以BCa为准,并在论文里说明。敏感性分析方面,可以用medsens命令做中介效应的敏感性分析,看需要多大的遗漏变量才能把间接效应推到不显著。medsens要求先跑sem或gsem,然后指定中介变量和结果变量。
* 中介效应敏感性分析 sem (M <- X cv1 cv2) (Y <- M X cv1 cv2), var(M) var(Y) medsens, m(M) y(Y) rho(0.1 0.3 0.5) * rho是误差相关系数,看不同rho下间接效应的变化rho(0.1 0.3 0.5)指定三个误差相关水平,输出对应的间接效应和置信区间。如果rho=0.5时间接效应仍然显著,说明结果对遗漏变量不敏感,结论稳健。
最后一个血泪经验:面板中介和调节的代码不难,难的是研究设计。跑之前先画路径图,把每个变量的角色标清楚,再动手写代码。我见过太多人代码跑得飞起,结果模型设定错了,返工重来。希望帮到你。
本文还有配套的精品资源,点击获取