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, 手寫批註
    • 盈餘管理, 特斯拉, 甲殼蟲, 論文重現
    • 易懂教程, 碼雲, 教程, 知乎

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