用好 esttab,导遍表格都不怕[中文 rtf 无乱码]
DreiStein
编辑于 2022年04月13日 23:57
收录于文集
共8篇

一年一度肝论文来临!对于使用 Stata 软件的小朋友们来说,最头疼的无非就是结果终于显著了,表格终于排版好了。结果却因为这样或那样的原因(调整小数位数,更新数据,替换模型等等),需要更新我们的结果,这时候重新再跑一遍代码倒是无妨,重新去调整格式真是要了卿命了。那么,今天,趁着 estout 包更新,为大家带来非常细致入微的导出模板吧。


先决条件:

  1.  可以访问github,因为截止今天(2022年3月25日),stata官方库ssc尚未同步更新最新命令(主要是修正了中文在rtf中的乱码问题)

  2. 拥有stata 14或以上版本软件,stata 13或以下版本命令操作相同,但是需要在命令最后加上 nortfencode 以保证导出结果中文显示正常。

⚠️注意:以下操作均使用stata自带数据库

代码块
clike
自动换行
复制代码
/*安装 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自带的表格模板一键完成)

在此,我直接给出所有代码,之后我们一段一段讲解

代码块
clike
自动换行
复制代码
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 的用法,跑数据部分不是我们关心的重点。

代码块
clike
自动换行
复制代码
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`是让这两行中间的命令任意换行,直到遇到英文分号才算完成一句命令,通常可用 `///` 来代替

代码块
clike
自动换行
复制代码
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)

代码块
clike
自动换行
复制代码
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()`指定模型分组情况,也就是表头数字上方的总体说明,不需要可以不加,这个说明需要后期手动进行 合并并居中 操作

代码块
clike
自动换行
复制代码
#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 中查找