B6. do 文档

作者: 连玉君 (中山大学)
邮箱:

Stata 有三种命令执行方式,对比如下:

任何一个好的研究项目的必备特征就是具有好的重复性,而借助 Do-file 可以轻松地实现结果的可重复性。下面介绍如何使用 Do-file。本节内容主要源于如下推文 (. lianxh dofile do文档):

1. 新建、保存和打开 dofile

A. 新建和保存 Do-file

方法 1:点击菜单。点击 Stata 主界面第二行倒数第六个按钮 (形似一个空白的记事本上有一支黄色铅笔)。

采用菜单方式新建 dofile

方法 2:使用 doedit 命令。在 Stata 命令窗口中输入 doedit 即可新建一个空白的 Do-file,默认名称为 Untitled.do。更好的处理方法是指定 dofile 的名称和存储路径,例如

  • 输入 doedit myAER,则会在当前工作路径下自动创建一个名为 myAER.do 的 dofile。
  • 输入 doedit D:/paper/myAER,则会在 D:/paper/ 路径下创建一个名为 myAER.do 的 dofile。

Stata_intro_create_dofile_01

我们可以在 dofile 中输入 Stata 命令,随后点击 「保存」 按钮,将其存入指定路径即可。例如,我们可以把新建的 Do-file 保存在 D:/Stata_Ex 文件夹下,名称为 Ex01.do,则该文件的完整存储路径为 D:/Stata_Ex/Ex01.do

注意:Stata 的 do文档 有自己专属的文件类型,后缀为 .do。因此,保存时,请不要更改其默认的文件类型:「Do-file (*.do)」。至于文件名,则没有特殊要求,中英文均可。

B. 打开 dofile

有两种方式可以打开电脑上已经存在的 dofile:命令行方式和菜单方式。

命令行方式

刚才我们新建的 Do-file 的完整存储路径为 D:/Stata_Ex/Ex01.do,因此,我们只需在 Stata 命令窗口中输入如下命令即可打开之 (当文件路径包含空格时,请务必附加半角模式下的双引号):

. doedit "D:/Stata_Ex/Ex01.do"

菜单方式

只需单击 Do-file 编辑器中的 「文件夹」按钮,定位至 Do-file 所在文件夹,找到需要打开的 Do-file 后,双击之即可打开。

打开 Do-file:菜单方式

3. dofile 的编写

如果你已经尝试过在命令窗口执行命令,那么,dofile 无非是将这些命令统一记录在一个文档中,以便后需修改和反复执行。

下面就是一个简单的 dofile:

*------------------------sample01.do ----
sysuse "auto.dta", clear

summarize price weight mpg  
scatter mpg weight  
reg mpg weight foreign
esttab, nogap
*------------------------sample01.do ----

在上述代码中,我们按照以下步骤逐步完成分析:

  • 加载数据:使用 sysuse 命令加载 Stata 自带的 auto.dta 数据集。
  • 描述性统计:使用 summarize 命令对变量 priceweightmpg 进行描述性统计,了解数据的基本特征。
  • 可视化分析:使用 scatter 命令绘制 mpgweight 的散点图,直观展示两者之间的关系。
  • 回归分析:使用 reg 命令以 mpg 为因变量,weightforeign 为自变量进行回归分析,探究变量之间的统计关系。
  • 结果输出:使用 esttab 命令将回归结果以简洁的表格形式输出,便于进一步解读和报告。

通过将上述步骤整合到 dofile 中,不仅提高了代码的可重复性,还使得分析过程更加清晰和高效。

4. dofile 的执行

你可以执行 dofile 中的部分代码,也可以一次性执行所有代码。你甚至可以在一个 dofile 中执行另一个 dofile 中的所有代码。

局部执行

多数情况下,我们只需要执行 dofile 中的部分命令。做法很简单:选中目标代码,点击下图所示按钮按钮;或按下快捷键 Ctrl+D

Stata_intro_excute_dofile_01

需要说明的是,你只需要选中某行中的一个以上的字符 (包括空格),Stata 就会执行该行的代码 (这与 R 不同)。

全部执行

若不选中任何代码块,而直接按快捷键 Ctrl+D,则 Stata 会一次性你执行 dofile 中的所有代码。

有时候,这种操作可能不是你的本意,而是误操作,此时你可以点击 Stata 主界面中的红色叉号 (第二行最后一个按钮),即可强制中断执行过程。

使用命令

我们也可以通过命令来执行整份 dofile:

do "D:/stata/personal/paper01/sample01.do"

这种方式主要用于大型项目。例如,对于复杂的项目,我们可以将不同的处理任务写在不同的 dofile 中,并将这些 dofile 统一放置在 ../codes 文件夹中。然后,可以在项目的根目录下设定一个名为 master.do 的主文档。这有几个好处:其一,整个项目的文档结构非常清楚;其二,我们可以单独执行某一部分,也可以执行 master.do 中的所有命令,以便运行项目中涉及的所有代码。

*------------------------ master.do ------begin---
global path  "D:/stata/personal/paper01"
cd "$path/codes"

do "01_data_clean.do"
do "02_summarize.do"
do "03_regression.do"
do "04_graph.do"
*------------------------ master.do ------over----

5. 添加注释语句

为了增加 dofile 的可读性,我们需要添加一些注释语句,主要包括:

  • 列明文档的标题、作者、生成日期等
  • 添加一些大标题,以便使文档结构清晰
  • 解释关键语句的目的和作用

Stata 中有三种添加注释语句的方法:

  1. 单行注释: 在行首使用 * 号,则该行内容会被自动忽略。一次只能注释一行语句。
  2. 行尾注释: 在一行命令之后至少加一个空格再加 // 字符,该行命令中 // 后的内容将被视为注释而忽略。快捷键:选中需要注释的语句,按 Ctrl + /
  3. 多行注释: 将需要注释的内容放在 /* */ 组合字符里边,被该组字符括起来的内容会被忽略。快捷键:选中需要注释的语句,按 Ctrl + Shift + /

6. 断行:三种方法

当所使用的命令很长需要换行的时候,可以使用以下三种方法来实现对命令的分行操作,从而实现分行后的命令承接上一行的操作:

  • M1. 配合使用 #delimit ;#delimit cr。使用 #delimit ; 命令,可以将换符设置为 ; (Stata 的默认换行符是回车键);使用#delimit cr 命令用来恢复默认换行符。
  • M2. 使用字符组合 /// 来实现上下行的连接。
  • M3. 用注释符 /* */ 来连接上下行,在操作过程中只需将上下行使用注释字符连接起来即可。

下面是一些典型的例子:

三种断行方式

7. dofile 编辑器的美化和语法高亮

在 dofile 编辑器中,依次点击:编辑首选项,可以在 常规颜色自动完成 等子选项卡中对 dofile 编辑器的配色、字体等进行个性化设定。

注意:完成本节介绍的各项设定后,可以参照 1.5 小节的方法保存为模板。

详情参见 help dofile[U] 16 Do-files,以及如下推文:

常规-选项卡:字体、字号、缩进等

  • 依次点击:编辑首选项常规

dofile 编辑器设置:常规选项卡

颜色-选项卡:语法高亮

  • 依次点击:编辑首选项颜色 (Colors)
  • 可以根据自己的喜好设定各类元素的配色。

dofile 编辑器设置:颜色选项卡

8. 良好的代码写作习惯

为了满足可重复性研究的要求,我们的代码不但要能正确执行,还应该清晰、易读。如下是一些 基本建议

  • 所有的操作 (包括: 数据处理、绘图、回归分析、结果输出等) 都要记录在 dofile 中,尽量避免手动处理
  • 每个项目 (每篇论文) 一个文件夹;文件分类存放,文件尽可能按照特定规则命名
  • 工作中,实时保存的是 dofiles,而不是 数据文件
  • 多加注释,以便增强代码的可读性
  • 注意排版,保证美观的同时,也便于查错

这里,先提供一个虚构的「dofile 样本」,以便让各位了解上述原则的基本精神。

  • 首先,在 dofile 的开头,标明了文件的生成日期、作者、作用等;
  • 其次,在「A. 基本设定」部分用全局暂元 global 定义了文件的存储路径和子文件夹的名称简写,以便后续将不同类新的文件分门别类地存放起来;
  • 再次D#.xxxS#.xxxR#.xxx 等部分依次为数据处理、统计分析和回归分析等内容。如此以来,即使 dofile 写的很长,仍然可以通过 Ctrl+F 快捷键快速搜索关键词定位。
  • 最后,值得注意是,我们频繁地使用了 localglobal,尤其是【R. 回归分析】部分。这种做法好处很多,比如,代码的结构看起来很清晰;很容易修改,只需在定义暂元的地方统一做一次修改即可,这可以大幅降低出错的概率;代码变得很简洁,可读性自然就提高了。
*------------------
*- 一个 dofile 范本    www.lianxh.cn
*------------------

* Version 1.2, 2035/1/2
* Author: 连家大公子
* 目的:分析家庭收入对子女学习成绩的影响

*------------
*-A. 基本设定

  global path "D:/myPaper/Income_Mark" //定义项目目录 
  
  // 需要预先在生成子文件夹:data, refs, out, adofiles
  global D    "$path/data"      //数据文件
  global R    "$path/refs"      //参考文献
  global Out  "$path/out"       //结果:图形和表格
  adopath +   "$path/adofiles"  //自编程序+外部命令 
  cd "$D"                       //设定当前工作路径
  set scheme s2color   

*-核心参考资料 (参考文献和文档都存放于 $R 文件夹下)
  shellout "$R/Safin_Federer_2005_Aust.pdf"

*------------
*-D1. 数据导入
  import excel using "$D/Income_Mark.xlsx", first clear
  save "_temp_"  // $D\ 可以省略,应为当前工作路径就是 $D
                 // 如果原始数据文件不大,此步骤可以省略

*------------
*-D2. 数据处理
  gen ……
  winsor2 ……
  ……
  save "data_dealed.dta", replace

*----------------------
*-S1. 基本描述性统计分析
  // 如果数据处理部分未作更新,可直接这里进行后续分析

  *-----表x:基本统计量-------
  use "data_dealed.dta", clear 
  local v " " //填入变量名
  local s "$Out/Table1_sum" //存储的文件名(或路径\文件名)
  logout, save("`s'") excel replace: ///
          tabstat `v', stat(mean sd p50 min max) f(%6.2f) c(s) 

  *-----表x:相关系数矩阵-------
  local v " " //填入变量名
  local s "$Out/Table2_corr" //存储的文件名(或路径\文件名)
  logout, save("`s'") excel replace: ///
          pwcorr_a `v', format(%6.2f) //star(0.05)

*-----------------
*-S2. 分组统计分析
  use "data_dealed.dta", clear  
  *-----表x:组间均值差异检验-------
  local v " " //填入变量名
  local s "$Out/ttable2" //存储的文件名(或路径\文件名)
  logout, save("`s'") excel replace: ///
          ttable2 `v', by(variable) format(%6.2f)

*-------------
*-R. 回归分析
  use "data_dealed.dta", clear    
  global y   "Mark"   //被解释变量
  global x   "Income" //基本解释变量
  global z   "edu_Dad edu_Mum Age##Age ……" //基本控制变量
  global w   "i.year i.industry i.race"    //虚拟变量
 *global opt ", vce(robust)" 
  global opt ", vce(cluster industry)" 
  
  reg $y $x        $opt
  est store m1
  reg $y $x $z     $opt
  est store m2
  reg $y $x $z $w  $opt
  est store m3

  *-----表x:回归结果-------
  local s "using $Out/Table3_reg.csv" //执行时包括这一行会输出Excel表格
  local m "m1 m2 m3"
  esttab `m' `s', nogap compress replace   ///
         b(%6.3f) s(N r2_a) drop(`drop')   ///
         star(* 0.1 ** 0.05 *** 0.01)      ///
         addnotes("*** 1% ** 5% * 10%")    ///
         indicate("行业效应 =*.industry" "年度效应 =*.year")

事实上,你若能在开始时遵守上述基本原则,就会慢慢发现它的好处远远大于你花费在排版上的成本。久而久之,你也会形成自己的代码风格。

下面,着重解释一些最重要的原则。

A. 实时保存 dofile 而不是数据文件

有些人在下班前喜欢把当天处理好的数据另存一份,这是个非常糟糕的习惯!

我的建议是:保存 dofile,而不是数据文件! 原因很简单,一个 dofile 只有几 k 或几十 k,但数据文件往往很大。如果保存了太多版本的数据文件,随后会导致严重的混乱,也就很难保证研究结果的可重复性。有些时候,数据处理环节比较复杂,代码运行时间也较长,可以保存 1-2 次过程数据,从而加快后续处理效率。要注意的是,在 dofile 中保存过程数据时,一定要添加注释语句,并将过程数据与原始数据存放到不同的文件夹中,以免混淆或误删。

B. 空格和注释语句

Stata没有空格和制表符的限制,为了让代码更加美观和易读,要合理使用空格和缩进。

rename k12_unique_id sid 
rename class_unique_id class_id 
rename teacher_name teacher 

*或者这样
rename k12_unique_id     sid 
rename class_unique_id   class_id 
rename teacher_name      teacher 
//可以看到后者更直观。

缩进对代码的跨行阅读也有帮助,在视觉上更容易接受:

// Good 
keep   sid class_id teacher grade1 /// 
       grade2 grade3 pass

// Bad  
keep sid class_id teacher grade1 /// 
grade2 grade3 pass

8. 文档结构

合理设置文档结构也是实现可重复研究的关键。请参阅如下推文:

如下论文的复现文档都设置了非常严谨的文档结构,供参考:

  • Ewens, M., Xiao, K., & Xu, T. (2024). Regulatory costs of being public: Evidence from bunching estimation. Journal of Financial Economics, 153, 103775. Link (rep), PDF, Google. -Appendix-, github-part-of-Data, -Replication-
  • Nagengast, A. J., & Yotov, Y. V., 2025. “Staggered Difference-in-Differences in Gravity Settings: Revisiting the Effects of Trade Agreements.” American Economic Journal: Applied Economics, forthcoming. Link, PDF, -Appendix-, Google, -Replication-
  • Barwick, Panle Jia, Shanjun Li, Liguo Lin, and Eric Yongchen Zou. 2024. "From Fog to Smog: The Value of Pollution Information." American Economic Review, 114 (5): 1338–81. DOI: 10.1257/aer.20200956 Link, PDF, -Replication-, -Appendix-, Google

9. 扩展阅读