Stata 可重复性报告系列A:动态文档命令 (dyn*)

作者:万莉 (北京航空航天大学)

连享会 - 与君分享 lianxh.cn

引言

在 Stata 16 发布页面, “truly reproducible reporting(可重复性报告)” 成为亮点之一。继 Stata 15 之后, Stata16 进一步引入和完善一系列相关命令。

对于 Stata 用户而言,我们可以用这些命令直接编写 dofile, 将报告正文、Stata 生成的图表等整合在一个文档中,自定义生成各种格式的文档(text,Word,PDF,Excel 或 HTML)。

更为重要的是,我们可实现可重复性研究,即报告中的数据、模型发生变化后,我们只需稍加修改 Stata 命令,便可输出更新后的文档,而不必逐个修改变动后的结果。

生成可重复性报告(Reproducible and automated reporting)的命令可分为两类:

  • 第一类:dyn 类——生成文档: 各种带 dyn 前缀的动态文档生成命令 (如 dyntext | dyndoc),用于生成 text、HTML 和 Word 文档。更重要的是,该命令支持 Markdown 文本格式语言。

  • 第二类:put 类——输出文档: 各种带 put 前缀的文档输出命令 (putdocx | putpdf | putexcel )。此类命令可自定义生成 Word、PDF 和 Excel 文件。

本文着重讲解第一类命令的使用方法。后续将介绍第二类命令。

连享会计量方法专题……

1. 准备工作:Markdown 和 Stata 动态标签

在学习动态文档命令前,我们先做一些准备工作。由于该类命令支持 Markdown 文本格式语言,且需要包含 Stata dynamic tags(动态标签),我们先大致了解下 Markdown 和 Stata dynamic tags(动态标签)。

1.1 什么是 Markdown ?

Markdown 是一种轻量级且易使用的标记语言,通过对标题、正文、加粗、链接等主要文本格式的预设编码,帮用户在写作中有效避免频繁的格式调整,获得更加流畅沉浸的写作体验。本质上,Markdown 是一种标记语法,它的格式更接近于纯文本。

了解 Markdown 的核心语句只需要五分钟。对比下图左右两栏,即可快速掌握 9 成以上的 Markdown 语法 ( Source: 「连玉君-五分钟 Markdown 教程」)。

连玉君-五分钟 Markdown 教程

1.2 什么是 Stata dynamic tags(动态标签)?

在动态文档命令 (dyndoc, dyntext) 中使用动态标签,用来定义执行某种操作,比如运行某个区域块,在文字中插入 Stata 命令的运行结果,导出图片等。

你可在 Stata 中输入 help dynamic tags 查看 dynamic tags 的具体使用说明。有两点需要注意:

  • / 的标签需成对出现。
  • 可进一步定义标签,在后面附加属性 (attributes);形如:<<dd_tags: attributes>>

可用的动态标签及相关使用方法,列在下方:

  • <<dd_version>>
    定义执行命令所需的最低版本;使用时需放在单行,推荐放在文档的首行。

    <<dd_version: version_number>>
    * version_number 不是指 Stata 版本,而是命令的版本。
    

    比如,当前 dyndoc 版本为 2, Stata 15 引入该命令, Stata 16 完善该命令。
    你可输入 dis c(dyndoc_version) 查看你所安装的 Stata 中该命令的相应版本。

  • <<dd_do>><</dd_do>>
    执行 Stata 代码块,并可选择性地将结果显示在文档中;使用时需单行放置。

    <<dd_do: attribute>>
    block of Stata code ...
    <</dd_do>>
    
  • <<dd_display>>
    在文档中显示某个 Stata 表达式的值;使用时可放在行内。

    <<dd_display: display_directive>>
    
    // 例子
    2*1*<<dd_display:%4.2f c(pi)>> = <<dd_display:%4.2f 2*1*c(pi)>>
    * 输出为 2*1*3.14 = 6.28
    
  • <<dd_docx_display>>
    只能用于 putdocx textblock 命令,在文档中显示某个 Stata 表达式的值及带格式的文本;使用时可放在行内。

    putdocx textblock begin
    ... text <<dd_docx_display text_options: display_directive>> text ...
    putdocx textblock end
    
    // 例子
    putdocx textblock begin
    2*1*<<dd_docx_display bold:%4.2f c(pi)>> = <<dd_docx_display bold:%4.2f 2*1*c(pi)>>
    putdocx textblock end
    * 输出为 2*1*3.14 = 6.28 (其中 3.14 和 6.28 为粗体)。
    
  • <<dd_graph>>
    插入图片;使用时可放在行内。

    <<dd_graph: attribute>>
    
  • <<dd_include>>
    将外部文件的内容插入到文档中;使用时需放在单行。

    <<dd_include: filename>>	
    
  • <<dd_ignore>><</dd_ignore>>
    处理时忽略这两个标签内的代码;使用时需单行放置。

  • <<dd_skip_if>><<dd_skip_else>><<dd_skip_end>>
    按某条件显示文本;使用时需单行放置。

    <<dd_skip_if: Stata expression>>
    lines of text ...
    <<dd_skip_end>>
    * 或者
    <<dd_skip_if: Stata expression>>
    lines of text ...
    <<dd_skip_else>>
    lines of text ...
    <<dd_skip_end>>
    
  • <<dd_remove>><</dd_remove>>
    删掉这两个标签内的内容;使用时可放在行内。

    ... <<dd_remove>>text to remove ...
    lines of text to remove ...
    text to remove ... <</dd_remove>> ...
    

连享会计量方法专题……

2. 命令一:dyntext

help dyntext //输出格式为 text 文本(.txt, .html, .do)

2.1 语法结构

dyntext srcfile [arguments], saving(targetfile) [options]

其中 srcfile 是包含 dynamic tags 的纯文本格式,即我们要转换的文档;targetfile 是输出的文档。srcfile 和 targetfile 的格式均为 text 文本(.txt, .html, .do)。

  • 选项说明 (options)
    • saving(targetfile): 指定要保存的目标文件,saving( )是必需的。
    • replace: 如果目标文件已经存在,替换目标文件。
    • noremove:处理时忽略<<dd_remove>> 和 <</dd_remove>>。
    • nostop:运行过程中有错误时,不中断。

2.2 范例

我们先新建一个 do 文件(也可以是 .txt 或 .html),命名为 dyntext_input1,输入内容为 *----- 间的内容。

*--------------------------begin dyntext_input1.do------------------------
In this analysis, we are going to discover 
   the mean miles per gallon of cars in 
   1978!

<<dd_do>>
sysuse auto.dta, clear
quietly summarize mpg
dis r(mean)
<</dd_do>>
*--------------------------end dyntext_input1.do---------------------------

接着我们使用 dyntext 命令,转换文档,如下:

dyntext dyntext_input1.do, saving(dyntext_output1.txt) replace

我们可以通过命令 shellout 查看输出结果,也可以在当前路径直接打开 dyntext_output1.txt

ssc install outreg2 // 安装此命令,调用shellout命令
shellout "dyntext_output1.txt"

输出结果如下:

*--------------------------begin dyntext_output1.txt------------------------
In this analysis, we are going to discover 
   the mean miles per gallon of cars in 
   1978!

. sysuse auto.dta, clear
(1978 Automobile Data)

. quietly summarize mpg

. dis r(mean)
21.297297
*--------------------------end dyntext_output1.txt---------------------------

3. 命令二:dyndocx

help dyndoc //输出格式为 text 文本(.html, .docx)

3.1 语法结构

dyndoc srcfile [arguments] [, options]

其中 srcfile 是包含 dynamic tags 的 Markdown 格式的文档(.txt, .md, .do),即我们要转换的文档。

  • 选项说明 (options)
    • saving(targetfile): 指定要保存的目标文件,saving( )不是必需的。
    • replace: 如果目标文件已经存在,替换目标文件。
    • hardwrap:用 HTML 换行符的标签 <br> 替换 Markdown 文档中的实际换行符。
    • nomsg:Stata 结果输出界面不再显示指向目标文件的链接信息。
    • nostop:运行过程中有错误时,不中断。
    • [*]embedimage:输出的 HTML 文件中插入的图像文件为 Base64 编码。
    • [*]docx:输出 Word 文档,而不是 HTML 文件。

需要特别说明的是:继 Stata 15 后,Stata 16 对该命令进行了完善,带 [*] 的选项不适用于 Stata 15。

3.2 范例 1:输出 HTML 文件

我们先新建一个 do 文件(也可以是 .txt 或 .md),命名为 dyndoc_example,输入内容为 *----- 间的内容。

*--------------------------begin dyndoc_example.do------------------------
<<dd_version: 2>>
<<dd_include: header.txt>>


Blood pressure report
===============================================================

We use data from the Second National Health and Nutrition Examination Survey
to study the incidence of high blood pressure.

<<dd_do:quietly>>
webuse nhanes2, clear
<</dd_do>>

## Logistic regression results

We fit a logistic regression model of high blood pressure on
weight, age group, and the interaction between age group and sex.
 
~~~
<<dd_do>>
logistic highbp weight agegrp##sex, nopvalues vsquish
<</dd_do>>
~~~

## Interaction plot

<<dd_do:quietly>>
margins agegrp#sex
marginsplot, title(Age Group and Sex Interaction) ///
        ytitle(Expected Probability of High Blood Pressure) ///
        legend(ring(0) bplacement(seast) col(1))
<</dd_do>>

<<dd_graph: saving("interaction.png") replace height(400)>>
*--------------------------end dyndoc_example.do---------------------------

其中,有以下几点需要注意:

  • 上述代码中,第二行 「<<dd_include: header.txt>>」语句中的 header.txt 文件是 HTML 代码,用来定义输出文件的样式 (类似于 Word 中模板文件)。你可以调整里面的 stmarkdown.css 属性来改变样式 (关于 CSS,参见 「CSS 教程 | 菜鸟教程」)。当前工作路径下必须同时包含 header.txtstmarkdown.css。你可以删掉上述 <<dd_include: header.txt>> 语句后对比一下输出结果有何差异。
  • === 定义报告的标题。
  • ## 定义章节标题。
  • <<dd_do:quietly>> 执行代码时,不显示代码和结果。
  • 若用 Stata 15 运行,则需改成 <<dd_version: 1>>。

接着我们使用 dyndoc 命令对上述进行转换:

dyndoc dyndoc_example.do, replace

我们可以通过命令 shellout 查看输出结果,也可以在当前路径直接打开 dyndoc_example.html

ssc install outreg2 // 安装此命令,调用shellout命令
shellout "dyndoc_example.html"

输出结果如下:

dyndoc_example1_html.png

注意:用不同浏览器打开,展示的结果略有差异;还可在浏览器页面查看源代码(一般单击右键可见)。

3.3 范例 2:输出 Word 文档

利用范例 1 中的输入文件,我们在 dyndoc 后添加 docx 选项,便可将输出结果保存为 Word 文档。注意:范例 2 需使用 Stata 16 及以上版本。

dyndoc dyndoc_example.do, docx replace

* 也可以用下述命令
 
html2docx dyndoc.html, replace

我们可以通过命令 shellout 查看输出结果,也可以在当前路径直接打开 dyndoc_example.docx

ssc install outreg2 // 安装此命令,调用shellout命令
shellout "dyndoc_example.docx"

输出结果如下:

dyndoc_example1_docx.png

3.4. 文档结构设定:用 dyndoc 写论文

我们可以使用 dyndoc 命令写论文,但是比较头疼的事情是,每次更新时都需要重新写转换文档的命令。这种情况下,我们按如下基本思路进行处理:

  1. 为每篇论文建立一个文件夹,比如命名为 Mypaper_2019
  2. 在该文件夹里新建一个 do 文件,命名为 _Main,用来保存转换文档用的命令,比如 dyndoc dyndoc_example.do, docx replace
  3. 在该文件夹里新建一个 do 文件,命名为 Body,当作论文主文档(包含实质内容,即我们要转换的文档),比如上例中的 dyndoc_example.do 文件。

这样,每次修改或更新这篇论文时,就只需在 Body.do 中修改,然后输入命令 do _Main.do,直接运行 _Main.do 即可。

若要进一步优化,我们可以在这个文件夹里新建一些子文件夹,如 DataOutputFigs 等,用于存储不同类型的文件。这样,就可以保证每篇论文的文件结构都很清晰。即使时隔很久后,我们也可以很顺利地修改和更新论文。

一个一般化的文件结构如下:

结语

可通过 help dyntexthelp dyndoc 参考更多官方范例,相关数据和文件下载地址如下:

  • https://www.stata-press.com/data/r15/markdown/
  • https://www.stata-press.com/data/r16/reporting/

如何重复性分析、规范地报告结果是实证研究中的难点之一。 我们可以用 dyntextdyndoc 直接写 dofile,并将报告正文和图表等整合,自定义输出文本,HTML 或 Word 格式的报告,即所谓的一种输入,多种输出。这在很大程度上能减少实证研究中的工作量。

相关链接


关于我们

  • Stata连享会 由中山大学连玉君老师团队创办,定期分享实证分析经验。直播间 有很多视频课程,可以随时观看。
  • 你的颈椎还好吗? 您将 ::连享会-主页::::连享会-知乎专栏:: 收藏起来,以便随时在电脑上查看往期推文。
  • 公众号推文分类: 计量专题 | 分类推文 | 资源工具。推文分成 内生性 | 空间计量 | 时序面板 | 结果输出 | 交乘调节 五类,主流方法介绍一目了然:DID, RDD, IV, GMM, FE, Probit 等。
  • 公众号关键词搜索/回复 功能已经上线。大家可以在公众号左下角点击键盘图标,输入简要关键词,以便快速呈现历史推文,获取工具软件和数据下载。常见关键词:
    • 课程, 直播, 视频, 客服, 模型设定, 研究设计,
    • stata, plus,Profile, 手册, SJ, 外部命令, profile, mata, 绘图, 编程, 数据, 可视化
    • DID,RDD, PSM,IV,DID, DDD, 合成控制法,内生性, 事件研究
    • 交乘, 平方项, 缺失值, 离群值, 缩尾, R2, 乱码, 结果
    • Probit, Logit, tobit, MLE, GMM, DEA, Bootstrap, bs, MC, TFP
    • 面板, 直击面板数据, 动态面板, VAR, 生存分析, 分位数
    • 空间, 空间计量, 连老师, 直播, 爬虫, 文本, 正则, python
    • Markdown, Markdown幻灯片, marp, 工具, 软件, Sai2, gInk, Annotator, 手写批注
    • 盈余管理, 特斯拉, 甲壳虫, 论文重现
    • 易懂教程, 码云, 教程, 知乎

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章