
一年一度肝论文来临!对于使用 Stata 软件的小朋友们来说,最头疼的无非就是结果终于显著了,表格终于排版好了。结果却因为这样或那样的原因(调整小数位数,更新数据,替换模型等等),需要更新我们的结果,这时候重新再跑一遍代码倒是无妨,重新去调整格式真是要了卿命了。那么,今天,趁着 estout 包更新,为大家带来非常细致入微的导出模板吧。
先决条件:
可以访问github,因为截止今天(2022年3月25日),stata官方库ssc尚未同步更新最新命令(主要是修正了中文在rtf中的乱码问题)
拥有stata 14或以上版本软件,stata 13或以下版本命令操作相同,但是需要在命令最后加上 nortfencode 以保证导出结果中文显示正常。
⚠️注意:以下操作均使用stata自带数据库
/*安装 esttab 包含在 estout 包中*/
net install estout, replace from("https://raw.githubusercontent.com/benjann/estout/master/")
/*使用 stata 自带数据演示*/
use "http://www.stata-press.com/data/r16/nlswork.dta",clear
xtset idcode year // 指定面板数据
glo y ln_wage // 因变量
glo x hours // 自变量
glo z c_city // 工具变量
glo m race // 调节变量
glo c grade age // 控制变量
glo f i.year i.ind_code // 年份和行业固定效应
// 变量标签标记为中文
label var $y "工资"
label var $x "工时"
label var $z "中心城市"
label var $m "种族"
label var grade "学历"
label var age "年龄"
// 值标签标记为中文
label define racelbl 1 "白人" 2 "黑人" 3 "其他", replace
那么,废话不多说,先展示最终结果(注意,该结果仅仅调整了页面方向、根据页边距调整表格宽度,对几个表头合并并居中,其余未做任何处理)

描述性统计表直出

相关系数表直出

分组 t 检验表仅对三个表头做了 合并并居中

回归结果仅对表头做了 合并并居中 以及 根据窗口自动调整表格
是不是很直接很接近最后需要的格式?最多只需要调整 字体+表格边线磅数 就可以直接使用了(而这一步完全可以通过word自带的表格模板一键完成)
在此,我直接给出所有代码,之后我们一段一段讲解
eststo tabsum:estpost sum $y $x $z $m $c , detail listwise
eststo tabcor:estpost corr $y $x $z $m $c ,matrix listwise
bysort $z : eststo: estpost sum $y $x $m $c , listwise
eststo tabttest: estpost ttest $y $x $m $c ,by(${z}) listwise
eststo olsbase: reg $y $c $f , vce(cluster idcode)
eststo olsmain: reg $y $x $c $f , vce(cluster idcode)
eststo olsint : reg $y c.${x}##ib3.${m} $c $f , vce(cluster idcode)
eststo regivm : ivregress 2sls $y (${x} = ${z}) $c $f , vce(cluster idcode)
eststo regivi : ivregress 2sls $y (${x} c.${x}#ib3.${m} = ///
${z} c.${z}#ib3.${m}) ib3.$m $c $f , vce(cluster idcode)
#delimit ;
esttab tabsum using mytable.rtf, replace label
title(描述性统计表)
cells((sum_w( label(观测值))
mean(fmt(3) label(均值))
sd(fmt(3) label(标准差))
min(fmt(3 0 0 0 0 0) label(最小值))
p25(fmt(3 0 0 0 0 0) label(1/4位))
p50(fmt(3 0 0 0 0 0) label(中位数))
p75(fmt(3 0 0 0 0 0) label(3/4位))
max(fmt(3 0 0 0 0 0) label(最大值))))
nomtitle nonumber noobs compress nogap;
esttab tabcor using mytable.rtf, append label
title(相关系数表)
b(4) unstack not nomtitle noobs nonumber nolegend
note({\sup *} {\i p} < 0.1
{\sup **} {\i p} < 0.05
{\sup ***} {\i p} < 0.01)
nogap compress starlevel(* 0.1 ** 0.05 *** 0.01);
esttab est3 est4 tabttest using mytable.rtf, append label
title(分组 t 检验表)
cells((sum_w(pattern(1 1 0) label(观测值))
mean(pattern(1 1 0) fmt(3) label(均值))
sd(pattern(1 1 0) fmt(3) label(标准差))
b(pattern(0 0 1) fmt(3) label(均值差异) star)
p(pattern(0 0 1) fmt(3) label("{\i p} 值"))))
mgroup("非中心城市组" "中心城市组" "组间差异", pattern(1 1 1))
starlevel(* 0.1 ** 0.05 *** 0.01) noobs nomtitle
nonumber nogap compress;
esttab olsbase olsmain olsint regivm regivi using mytable.rtf, append label
title(回归结果) b(3) se(3) brac nogap compress order($x *.${m}*)
note(注:括号中为聚类稳健标准误)
indicate("年份=*.year" "行业=*.ind_code",label("控制" "")) nobase interact(" × ")
mgroup("基本模型" "OLS回归" "工具变量回归",pattern(1 1 0 1 0))
mtitle("基本" "主效应" "调节效应" "主效应" "调节效应")
stat(N r2 r2_a F chi2, fmt(0 3 3 3 3) star(f chi2)
label("样本量" "{\i R}²" "调整{\i R}²" "{\i F} 值" "{\i χ}²"));
#delimit cr
下面我们详细讲解 esttab 的用法,跑数据部分不是我们关心的重点。
eststo tabsum:estpost sum $y $x $z $m $c , detail listwise
#delimit ;
esttab tabsum using mytable.rtf, replace label
title(描述性统计表)
cells((sum_w( label(观测值))
mean(fmt(3) label(均值))
sd(fmt(3) label(标准差))
min(fmt(3 0 0 0 0 0) label(最小值))
p25(fmt(3 0 0 0 0 0) label(1/4位))
p50(fmt(3 0 0 0 0 0) label(中位数))
p75(fmt(3 0 0 0 0 0) label(3/4位))
max(fmt(3 0 0 0 0 0) label(最大值))))
nomtitle nonumber noobs compress nogap;
#delimit cr 想要输出前3张表(描述性统计、相关系数、分组t检验)必须首先使用 `estpost` 命令进行sum、corr、ttest的分析,并且通过 `eststo` 存在对应标记中方便调用,大家直接将自己的变量代入就好,不多讲述。这里主要讲的是如何调整你表格的输出格式:
`replace` 分别指定每次运行 esttab 都对 mytable.rtf 清空并重新输入数据;`label` 表示用变量的标签(一开始加上的中文标签)汇报,而不是用变量名,建议使用,下同。
指定小数位数,可以看到,我的表格中,观测值是整数,整数型变量的最小值-最大值也是整数,其余均为3位小数,这该如何指定呢?就是通过 `fmt()` 一行一行进行指定,注意到除了第一行3位小数,其余变量均为整数型,因此上面的`fmt(3 0 0 0 0 0)`可以简写为`fmt(3 0)`因此建议大家对自己用到的变量按照类别来排列,或者活用 `local`和 `global` 功能。
最后一行是去除冗余信息的一行,基本不用调整,我建议大家原样保留
指定` #delimit ;` 和 `#delimit cr`是让这两行中间的命令任意换行,直到遇到英文分号才算完成一句命令,通常可用 `///` 来代替
eststo tabcor:estpost corr $y $x $z $m $c ,matrix listwise
#delimit ;
esttab tabcor using mytable.rtf, append label
title(相关系数表)
b(4) unstack not nomtitle noobs nonumber nolegend
note({\sup *} {\i p} < 0.1
{\sup **} {\i p} < 0.05
{\sup ***} {\i p} < 0.01)
nogap compress starlevel(* 0.1 ** 0.05 *** 0.01);
#delimit cr 对于相关系数表,基本就是指定小数位数和显著性水平
`append` 代表将数据录入在 mytable.rtf 已有数据后面,如果希望一表一文档可以更换using [文档名].rtf 后 改为 `replace`。下同
`b(4)` 代表 4 位小数,大家可以自己替换
`note()` 中为表格下方的显著性说明,默认的说明在 `legend` 中,只是不会对字母 p 做斜体,所以我自己写了一下{\i p}如果有希望斜体的部分都可以做这种修改。不介意的小伙伴可以把 `nolegend`去掉,并替换 `note()` 中的内容
`starlevel` 指定显著性标记,大家可以按自己喜好来,但数值必须是递减的(eg. + 0.15 * 0.1 ** 0.05)
bysort $z : eststo: estpost sum $y $x $m $c , listwise
eststo tabttest: estpost ttest $y $x $m $c ,by(${z}) listwise
#delimit ;
esttab est3 est4 tabttest using mytable.rtf, append label
title(分组 t 检验表)
cells((sum_w(pattern(1 1 0) label(观测值))
mean(pattern(1 1 0) fmt(3) label(均值))
sd(pattern(1 1 0) fmt(3) label(标准差))
b(pattern(0 0 1) fmt(3) label(均值差异) star)
p(pattern(0 0 1) fmt(3) label("{\i p} 值"))))
mgroup("非中心城市组" "中心城市组" "组间差异", pattern(1 1 1))
starlevel(* 0.1 ** 0.05 *** 0.01) noobs nomtitle
nonumber nogap compress;
#delimit cr 输出 t 检验表时,相当于输出 3 个模型—— 2 个分组统计 + 1 个 t 检验
`pattern(1 1 0) / pattern(0 0 1)` 这个是说明这个统计量在哪个模型中显示(1),哪个模型中不显示(0)。不需要修改
`b(...star)` 意味着对 t 检验系数差异标 * ,如果不需要,可以不加
`mgroup()`指定模型分组情况,也就是表头数字上方的总体说明,不需要可以不加,这个说明需要后期手动进行 合并并居中 操作
#delimit ;
esttab olsbase olsmain olsint regivm regivi using mytable.rtf, append label
title(回归结果) b(3) se(3) brac nogap compress order($x *.${m}*)
note(注:括号中为聚类稳健标准误)
indicate("年份=*.year" "行业=*.ind_code",label("控制" "")) nobase interact(" × ")
mgroup("基本模型" "OLS回归" "工具变量回归",pattern(1 1 0 1 0))
mtitle("基本" "主效应" "调节效应" "主效应" "调节效应")
stat(N r2 r2_a F chi2, fmt(0 3 3 3 3) star(f chi2)
label("样本量" "{\i R}²" "调整{\i R}²" "{\i F} 值" "{\i χ}²"));
#delimit cr `b(3)` 和 `se(3)` 分别代表系数和标准误的小数位数,如果希望汇报 t 值或 z 值,可以用 `t(3)` 或 `z(3)` 代替,注意 `t()` 和 `se()` 只能二选一,不能全都要!!!
`brac` 代表使用方括号 括住 se/t/z ,默认是圆括号,如果希望使用圆括号可以不指定
`order()` 用于指定变量排列顺序,可以把最希望展示在前面的几个变量写上
`indicate()` 可以简写为 `i()` 用于说明各种固定效应(回归方程中通过 i. 指定的)注意一定要用英文双引号括住,里面的label()用于指定是否包括的文字,默认是 Yes 和 No,可以根据需要修改,需要英文双引号
`nobase` 表示不显示对照组(i. 变量中的对照组)通常需要指定
`interact()` 指定用来替换交互项的符号,默认是 # ,必须要同时指定 `label` 才有用(即必须将变量用label表示)
`mtitle()` 用于指定模型名称,如果不需要,可以用 `nomtitle`替换;另外如果不需要模型上方的数字编号,可以指定 `nonumber`。
`stat()` 用于指定一些统计量 格式是 stat(统计量的名称, fmt(统计量小数位数) star(需要标*的统计量) label(统计量的标签)) 统计量的名称可以在回归之后通过 ereturn list 在 scalar 中查找