Stata程序:10 分钟快乐编写 ado 文件

发布时间:2020-12-09 阅读 11404

Stata连享会   主页 || 视频 || 推文 || 知乎

温馨提示: 定期 清理浏览器缓存,可以获得最佳浏览体验。

New! lianxh 命令发布了:
随时搜索连享会推文、Stata 资源,安装命令如下:
. ssc install lianxh
使用详情参见帮助文件 (有惊喜):
. help lianxh

课程详情 https://gitee.com/arlionn/Course   |   lianxh.cn

课程主页 https://gitee.com/arlionn/Course

作者:余影(中山大学)
邮箱yuying29@mail2.sysu.edu.cn

指导教师: 连玉君(中山大学,arlionn@163.com


目录


导师寄语:


余影同学是岭南学院金融专业的大三本科生,一个爱笑,身材高挑,皮肤白净的女生,超喜欢摆弄 Stata,写程序。

这篇推文就是余影同学修习我的「实证金融」课程过程中完成的一个小作业。这次 作业 是学习 Stata 第三周时 (刚刚讲完第三讲 - Stata 程序简介) 布置的,目的是让大家学会编写 ado 文档的流程。任务很简单,就是实现一个阶乘运算,当然,我也设定了一些选做题目,比如,增加选项、批量处理、编写帮助文件等。同学们给出了多个版本的程序思路,都记录在了 这里

余影同学结合大家的思路,有进一步加入了对 tokenizegettokenreturn list 等命令的使用,让我们能够「管中窥豹」,从这个来小例子中几乎学到了 Stata 编程的多数知识要点。更有意思的是,她还专门花了 1 天时间学习 Mata 语句,也给出了一个 Mata 版本的程序。

大家的感触是,只要「动起来」,勇敢尝试,Stata 编程其实很简单。

这篇推文用了 3 天就完成了。

码云项目主页:10 分钟编写 ado 程序

连玉君
2020/12/14 12:57

本文讨论了一个在 Stata 使用过程中基础但非常重要的任务——编写 ado 文件。通过一个简单的例子——计算阶乘,由浅入深地讲解如何逐步编写满足不同需求的 ado 文件。

1. 初识 ado 文件

在使用 Stata 的过程中,我们可以在 Stata 的命令窗口输入各项命令,采用交互的方式定义程序。但在实际应用中,更常见的方式是通过创建 ado 文档 (automatic do-file) 来保存程序,将程序变为一个新的命令,在需要使用的时候,通过定义的 ado 文件(程序)的名称调用。相比起一遍又一遍地输入命令,这种方法既方便又不容易出错。

下面我们将创建一个最简单的 ado 文件:(myfact 为文件名)

capture program drop myfact
program define myfact
version 15
  dis "Hello,ado."
end

这是编写程序最为基本的一种格式。在最开始加入第一行是为了将 ado 文件的代码(若已经存在)从内存中删去,以便读入新版代码。随后以 program define 开头定义程序,可以加入 version 表明程序的版本,最后以 end 结尾。随后调用 myfact.ado 文件即可运行程序。

. myfact
Hello,ado.

2. 编写 ado 文件基本命令介绍

在这一部分中,我们将简要介绍编写 ado 文件的相关命令。而想要从例子出发由浅入深地了解程序编写技巧的读者可以先跳过这一部分,从第三部分看起,有不明白的地方再回头看这一部分的命令介绍。

2.1 program 命令

定义程序的基本语法结构如下:

program [define] pgmname [, [ nclass | rclass | eclass | sclass ] byable(recall[, noheader] | onecall) properties(namelist) sortpreserve plugin]

在这里, program define 是定义程序的基本命令,其中 define 可以省略;pgmname 为程序名;nclass 为默认项,用于表明程序的类型;rclasseclasssclass则表示程序的结果分别保存在r()e()s() 中,方便之后的调用。

2.2 capture 命令

我们可以在命令之前加入 capture,当命令出错的时候,自动跳过该行命令(不报错)并继续执行下面的代码。该命令语法结构如下:

capture [:] command

使用 capture 命令,命令的返回码会保存在 _rc 当中。如果想知道具体的报错信息,可以使用 dis _rc 命令。当没有运行错误时, _rc 等于 0,否则不为 0。

Note: 在编写程序时,可以使用 capture 来「包裹」一个可能出错的语句,继而根据其自动存储于 _rc 暂元中的返回值来判断该语句是否正确:若 _rc 中的数值为 0,则表示该语句正确,否则意味着该语句不正确。详情参见 help capturehelp _rc,以及 PDF 手册 [P] capture

2.3 args 命令

args macroname1 [macroname2 [macroname3 ...]]

有些时候,我们需要在程序中使用外部输入的变量。这时,我们可以使用 args 命令接收用户的输入参数。args 命令将第一个命令参数分配给暂元 macroname1,将第二个参数分配给暂元 macroname2,依此类推。在编写代码时,我们可以用`'引用其内容,如:

`macroname1' `macroname2'

2.4 syntax 命令

在编写程序时,我们可以使用 syntax 命令解析命令行,当输入的内容和指定的语法不同时,syntax 还会报错。 标准的 syntax 命令语法结构如下 ( [P] syntax ):

syntax [varlist | namelist | anything]   ///
       [if] [in] [using filename] [= exp] ///
       [weight] [, options]

对于 varlist,我们可以设置多种格式:

  • syntax varist 表示变量名 varist 必须设置
  • syntax [varist] 表示变量名 varist 可以设置也可以不设置
  • syntax varlist(min=2 max=4 numeric) 表示输入变量个数最少为 1,最多为 2,且必须为数值型,numeric 还可以换成string(字符型)、fv(factor variables)等。

我们还可以将 varlist 换成 newvarlist 或者 newvarname(表明生成新变量);换成 namelist 或者 name(表明输入的对象可以不是变量);如果还想进一步放宽要求(如输入的对象为数字),可以将 varlist 换成 anything,语法结构如下:

syntax anything(name=eqlist id="equation list")

其中输入参数命名为暂元 eqlist,将 anything 命名为 equation list(仅在报错时使用)。

2.5 confirm 命令

在编写程序时,如果想要判断输入的参数或者变量是否为某一类型,我们可以使用 confirm 命令。

confirm [integer] number string

不添加可选项 integer 时,命令用于确认输入参数为数字;加入可选项 integer 后命令用于确认输入参数为整数。同时 number 还可以换成 matrix(矩阵)、scalar(标量)等。

Note: 在编写程序时,confirm 命令经常与 capture 命令一起使用,详情参见 help confirm ([P] confirm) 和 help capture ([P] capture)。

3. 使用阶乘的例子逐步了解 ado 文件编写技巧

3.1 阶乘概念

阶乘是基斯顿•卡曼(Christian Kramp,1760 ~ 1826)于 1808 年发明的运算符号。一个正整数的阶乘(factorial)是所有小于及等于该数的正整数的积,并且 0 的阶乘为 1。

3.2 在 dofile 中实现特定数字的阶乘运算

在 Stata 中,我们可以使用 forvalues 命令 ( [P] forvalues ),通过循环计算阶乘。 例如计算 5 的阶乘,我们可以通过下述代码实现:

local k = 5    // 阶数
  local a = 1  // 阶乘
  forvalues i = 1/`k'{
    local a = `a'*`i'
  }

  dis "`k'! = " `a'

3.3 使用 ado 文件计算阶乘

在 3.2 中,如果我们需要多次计算阶乘必须不断改变 k 值并重复执行 dofile 中的命令,但是我们可以通过使用 ado 文件 简化这些步骤。

我们做了什么调整呢?

capture program drop myfact1
program define myfact1
version 15
  args k    // 定义暂元 k,用于接收用户输入的数字
  local a = 1
  forvalues i = 1/`k'{
    local a = `a'*`i'
  }
  dis "`k'! = " `a'
end

相对于 3.2 中的代码,我们在开始加入了 program define myfact1 ,在结尾处加入了 end,这样 Stata 就会自动将其视为命令。同时使用 args 命令,定义暂元 k,用于接收用户输入的数字。执行完上述代码,就可以通过定义的 ado 文件的名称 myfact1 进行调用,得到和 3.2 中一样的结果。

. myfact1  5
5! = 120

3.4 增加 ado 文件功能

在编写程序的过程中,我们必须考虑到用户的各种行为和需求。通过改进自己的程序,来识别错误的行为并给出有用的提示信息来满足用户的各种需求。下面我们将逐步增添程序的功能,完善上述计算阶乘的程序。

3.4.1 若用户输入的参数不是正整数,报错并提示

在计算阶乘的例子中,由于只有正整数才有阶乘( 0!=1 除外),在编写程序的时候,我们需要考虑到用户输入参数不为正整数的情况。如果用户输入的参数不是正整数,我们需要报错并给出有用的信息来提醒用户重新输入正整数。程序代码如下:

capture program drop myfact2
program define myfact2
version 15
capture syntax anything(name=k)
  if _rc{  // 用户忘了输入数字
    dis as error "You must enter an positive integer"
	exit
  }
  if wordcount(`"`k'"')>1{  // 用户输入了多个数字
    dis as error "You can only enter one integer"
	exit
  }
  capture confirm integer number `k' // 用户输入了非整数或文字
  if _rc{
    dis as error "You must enter a positive integer"
	exit
  }
  if `k'<0{  // 用户输入了负数
     dis as error "You must enter an positive integer"
	 exit
  }
  local a = 1  //计算
  forvalues i = 1/`k'{
    local a = `a'*`i'
  }
  dis "`k'! = "  `a'
end

相比于 myfact1,改进版的 myfact2 考虑了用户忘记输入数字、输入多个数字、输入非整数或文字以及输入负数的情况。使用 capture,如果用户忘记输入数字, _rc 不为 0,则输出 You must enter an positive integer ;使用wordcount(此时需注意暂元的引用方式),如果用户输入多个数字,输出 You can only enter one integer ;同时为了保证输入数字为整数,还可以使用 confirm 命令。

对上述程序进行调用可以得到

. myfact2 5
5! = 120

. myfact2
You must enter an positive integer

. myfact2 5 4
You can only enter one integer

. myfact2 A
You must enter a positive integer

. myfact2 -5
You must enter an positive integer

3.4.2 增加选项 format(),以便用户自定义结果的显示格式

除了考虑用户可能的输入参数的情况,我们还可以为程序增添定义输出格式的功能来满足用户的一般需求。程序代码如下:

capture program drop myfact3
program define myfact3
version 15
syntax anything(name=k) [, Format(string)]
  local a = 1
  forvalues i = 1/`k'{
    local a = `a'*`i'
  }
  dis "`k'! = " `format' `a'
end

为了定义输出格式,我们在 syntax 命令中加入了可选项 Format,若用户输入显示格式的代码,程序就将代码存储到暂元 format 中,并通过后续编写的代码,实现自定义结果的显示格式。

说明: 可选项 Format() 中的大写字母部分就是该选项可以缩写的程度。例如,若使用 [, Format(string)],用户在调用的时候可以缩写为 f(..);但是如果使用 [, format(string)],则不能缩写。

对上述程序进行调用可以得到

. myfact3 10, format(%-20.0g)
10! = 3628800

. myfact3 10, f(%-20.0g)
10! = 3628800

. myfact3 20
20! = 2.433e+18

. myfact3 20, format(%-20.0f)
20! = 2432902008179999700

Note: 关于格式设定可以查看简书——如何设定 Stata 中数字的显示格式

3.4.3 甄别错误输入和报错

在 3.4.1 中,我们讨论了如果用户输入的参数不是正整数的情况,而在加入 Format 选项后,我们还需要考虑用户输入的控制数据显示格式的代码有误的情况,若输入错误,我们需要报错并给出有用的提示信息。程序的代码如下:

capture program drop myfact4
program define myfact4
version 15
syntax anything(name=k) [, Format(string)]
  if "`format'" != ""{
    capture confirm format `format'
	if _rc{
	  dis as error "invalid format(`format'). It should be format(%10.0g)."
	  dis as text  "for help, see {help format}"
	  exit 198
	}
  }
  local a = 1
  forvalues i = 1/`k'{
    local a = `a'*`i'
  }
  dis "`k'! = " `format' `a'
end

相比于 myfact3,我们在 myfact4 中加入了条件判断:如果发现用户输入的 format 形式有误,则提示出错,并给出正确示范和查询途径。这大大方便了用户使用,减少了用户查询错误的时间。

若输入

. myfact4 5, format(1f)

我们可以得到

. myfact4 5, format(1f)
invalid format(1f). It should be format(%10.0g).
for help, see format
r(198);

3.4.4 产生新变量

通过前面的部分,我们已经大致了解了如何编写程序,并逐步增添功能。下面的内容我们将进行进一步的拓展,考虑如何产生新变量,并将阶乘的结果赋值给新变量。程序的代码如下:

capture program drop myfact5
program define myfact5
version 15
syntax anything(name=k) [, GENerate(string) Format(string)]
  local a = 1
  forvalues i = 1/`k'{
    local a = `a'*`i'
  }
  if "`generate'" != ""{
    gen `generate' = `a'
  }
  else{
    dis "`k'! = " `format' `a'
  }
end

为了产生新变量,我们在 syntax 命令中加入了可选项 GENerate(string)。若用户输入新变量名,程序就将变量名存储到暂元 generate (该暂元用于接收用户设定的 新变量名称,即 string ) 中,并通过后续的代码,实现产生新变量并将阶乘的结果赋值给新变量的结果。

运行程序后可进行以下程序测试:

clear
set obs 3
gen x = 1

myfact5 5, gen(x5)
myfact5 5, gen(x)
myfact5 5, gen(z1 z2)  // 输入了两个变量名
myfact5 5, gen(1ab)    // 非法变量名

3.4.5 利用可选项 rclass,生成并调用返回值

在编写程序的时候,我们可能不仅仅想要通过运行程序得出一个结果,还想要保存结果,以方便之后的调用。我们可以在 program 命令中加入可选项 rclass 来达到这种效果,程序的结果将保存在 r() 中以便调用。 在实际应用中,将结果保存在 r() 中有以下命令:

  • return scalar name = exp // 保存标量 scalar
  • return local name = exp // 保存局部宏 local
  • return matrix name [=] matname [, copy] // 保存矩阵 matrix

运行完程序后,我们可以通过 return list 命令调看程序的返回值。并通过 r() 调用返回值。

在阶乘的例子中,我们想要将阶乘的结果保存并调用,代码如下:

capture program drop myfact6
program define myfact6, rclass // New
version 15
syntax anything(name=k) [, Format(string)]
  local a = 1
  forvalues i = 1/`k'{
    local a = `a'*`i'
  }
  dis "`k'! = " `format' `a'
  return scalar kk = `a'       // New
end

我们通过倒数第二行代码将结果保存。随后可以通过 r(kk) 调用返回值:

若输入:

myfact6  5
return list
dis "K! = " r(kk)

我们可以得到:

. myfact6  5
5! = 120

. return list
scalars:
                 r(kk) =  120

. dis "K! = " r(kk)
K! = 120

3.4.6 多个数值的阶乘

在以上的例子中,我们专注于单个数值阶乘的计算,如果想要得到多个数值的阶乘需要重复调用 myfact 文件。但是实际上我们可以通过 tokenize ( [P] tokenize ) 和 gettoken ( [P] gettoken ) 命令实现对输入参数的解析,获取所需部分,进而实现多个数值阶乘的计算。

  • 使用 tokenize 解析输入参数的基本命令如下:

    tokenize [[`]"][string]["[']] [, parse("pchars") ]
    

    其中,string 代表要分解的参数的名称,可选项 parse("pchars") 表示用 pchars 作为各个部分的分隔符,默认为空格。tokenize 将参数分解为指定部分,并依次保存在局部宏 1、2 中…… 以下为使用 tokenize 的小例子: 输入

    *-tokenize
    local k = "3 5 7" // 字符串
    tokenize "`k'"    // 切割
    di "A=|`1'|, B=|`2'|, C=|`3'|, D=|`4'|"
    

    可以得到

    A=|3|, B=|5|, C=|7|, D=||
    
  • gettoken 提供了解析输入参数的另一种方式,基本命令如下:

    gettoken emname1 [emname2] : emname3 [, parse("pchars") quotes qed(lmacname) match(lmacname) bind]
    

    其中,可选项 parse("pchars") 表示用 pchars 作为各个部分的分隔符,默认为空格,该命令会获取 emname3 分隔符之前的参数,并将其储存在 emname1 中;如果加入了 emname2,剩下的参数则将存储在 emname2 中。 以下为使用 gettoken 的小例子:

    *-gettoken
    local k = "3 5 7"
    gettoken 1 k:k
    dis `1'
    gettoken 2 k:k
    dis `2'
    gettoken 3 k:k
    dis `3'
    

    可以得到

    . gettoken 1 k:k
    . dis `1'
    3
    . gettoken 2 k:k
    . dis `2'
    5
    . gettoken 3 k:k
    . dis `3'
    7
    

    想要进一步了解 tokenize ( [P] tokenize ) 和 gettoken ( [P] gettoken ) 命令的详情,可以使用 help tokenizehelp gettoken 命令查看。

继续阶乘的例子,为了实现多个数值的阶乘,我们使用了 tokenize 解析输入参数,代码如下:

capture program drop myfact7
program define myfact7, rclass
version 15
syntax anything(name=numlist) [, Format(string)]
tokenize "`numlist'"
local j = 1
while "``j''" !=""{     // `j' 表示房间号;``j'' 表示房间中的内容
  local a = 1
  local k = ``j''       // 注意暂元的引用方式
  forvalues i = 1/`k'{
    local a = `a'*`i'
  }
  dis "`k'! = " `format' `a'
  return scalar k`k' = `a'
  local j = `j' + 1
}
end

输入:

. myfact7 3 4 5
. return list

我们可以得到:

. myfact6 3 4 5
3! = 6
4! = 24
5! = 120

. return list
scalars:
                 r(k5) =  120
                 r(k4) =  24
                 r(k3) =  6

4. 在 ado 文件中使用 Mata

在第 3 部分中,我们已经简要介绍了编写 ado 文件的方法和技巧,而在实际编写 ado 文件中,我们还可以加入 Mata 以加快文件执行的速度。许多常用的计量经济学程序可以用矩阵简明地表示,Mata 可以使 Stata 中使用的特定程序的编程更加容易。例如,有 Roodman 博士编写的 xtabond2.ado 通过使用 Mata 语句使其运算速度提高了 10 倍以上。

关于 Mata 的入门详见连享会推文:

下文将主要介绍如何在 ado 文件中使用 Mata。

首先沿用第三部分阶乘的例子,我们可以尝试使用 Mata 计算 5 的阶乘:

mata                 //进入mata环境
  v=(1..5)
  sum1 = 1
  for (i=1; i<=length(v); i++) {
    sum1 = sum1*v[i]
  }
  (sum1)
end                  //退出mata环境

而为了实现不同阶乘的计算,我们可以将 Mata 与 ado 文件联用来简化重复执行上述步骤。

方式一: 直接调用 Mata 函数

直接调用 Mata 自带的函数 factorial() 计算阶乘,在 ado 文件中输入单行命令 mata: 实现 Mata 环境的调用。

capture program drop myfact10
program define myfact10
version 15
args k    // 定义暂元 k,用于接收用户输入的数字
mata: factorial(`k')
end

方式二: 自行创建 Mata 函数,并在 ado 文件中调用

若 Mata 提供的函数无法满足我们的计算需要,就需要我们自己造轮子了。这里,我们自己定义了一个新函数 ifact(),然后在标准的 ado 文件中调用它。

capture program drop myfact7
program define myfact7
version 15
args k    // 定义暂元 k,用于接收用户输入的数字
mata: ifact(`k')
end

capture mata mata drop ifact()
version 15
mata:
real rowvector ifact(real scalar k)
{
real rowvector a
a = (1..k)
sum1 =1
for (i=1; i<=length(a); i++) {
  sum1 = sum1*a[i]
}
return(sum1)
 }
end

调用上述两个 ado 文件我们可以得到:

. myfact7 5
  120
. myfact8 5
  120

5. 帮助文件的编写

在编写完一个新命令后,我们不仅可以自己使用,还可以分享给其他需要的人,这是 Stata 开放性的一种体现。而 Stata 中最热门的命令,如 outreg2 (Roy Wada), estout (Ben Jann) 和 winsor2(Lian Yu-jun) 等,在使用时都可以通过 help 命令查询其具体功能和应用例子。为了方便用户的使用,我们也可以为自己编写的命令编写帮助文件,向用户更好地介绍命令的使用方法和相关信息。

类似于 dofile 或 adofile,Stata 的帮助文件也是一个文本文件。因此,我们可以用 Stata 的 Do-file 编辑器来编辑帮助文件。

帮助文件的内容需要借助 Stata 特有的标记和控制语言 (Stata Markup and Control Language),用于产生 加粗斜体,段落缩进等效果。详情参见 help smcl

对于多数用户而言,只是偶尔写写帮助文件,建议各位使用「修补法」,即找个现成的帮助文件修改一下即可。当然,你也可以挑战一下自己,自己设计一个风格独特的帮助文件。此外,你也可以借助外部命令 makehlp 自动化生成帮助文件的核心内容,如选项说明等 ( 输入 ssc install makehlp 即可安装)。

需要注意的是,无论是新编写的 myfact.ado 文档还是将要编写的 myfact.sthlp 文档,都需要放在 Stata 能够「找得到」的地方。你可以在命令窗口输入 adopath,在这个清单下的目录中的文档是 Stata 能够「找得到」的。

所以,我们可以把新定义的程序文件放在 「..\ado\plus\m」文件夹下,也可以放在其他文件夹下,如「F:\myado」,然后使用 adopath + F:\myado 将该路径添加到 Stata adofiles 路径清单中即可,详情参见 help adopath,以及如下推文:

此外,对于经常使用 Markdown 写东西的读者而言,也可以考虑使用 Markdown 语言来编写帮助文件,详情参见 E. F. Haghish - MarkDoc,以及 MarkDoc - Github 主页

5.1 修补法产生帮助文件

一种最简便的办法就是「修补法」:

  • 第一步:找一份与我们要写的帮助文件风格相似的现有帮助文件,如 winsor2.sthlp (存放于 「..\ado\plus\w」 子文件夹下),用 dofile 编辑器打开它 (可以把它视为一个 dofile)
  • 第二步:将 winsor2.sthlp 另存为 myfact.sthlp (注意:文件的保存类型要选择 .sthlp)
  • 第三步:把 winsor2 统一替换为 myfact,其它内容酌情修改。

完成第二步时,你输入 help myfact 就已经可以看到新的帮助文件了,在做第三步的过程中,可以不断刷新已经打开的 myfact.sthlp 来查看编辑效果。

5.2 从零开始编写帮助文件

  • 首先,我们需要新建一个空白的 dofile 文档,将其保存为 myfact.sthlp。注意:文件名与程序名同名,保存类型为 .sthlp,如下图所示:
  • 在编写帮助文件时,主要包括以下内容:
Title               //命令的名称
Syntax              //命令的语法结构
Description         //简介
Options             //可选项介绍
Examples            //应用实例
Author              //作者信息
  • .sthlp文件编写的主要代码及功能如下:
{title:myfact3}         //将 myfact3 以标题形式显示
{cmd:myfact3}           //加粗显示 Stata 命令
{stata:`"myfact3 10"'}  //设置“超链接”,在帮助文件中点击即可自动帮用户在命令窗口输入代码
{cmdab:F:ormat:}        //显示 Stata 命令,Format中F可小写

*语义标签
{hi:myfact3}            //突出显示
{it:myfact3}            //斜体
{bf:myfact3}            //粗体

*排版
{hline}                 //分割线
{p 4 2 5}               //第一行空4个空格; 之后每行前空2个空格; 行右侧留5个空格的空间
{pstd}                  //和{p 4 4 2}相同
{phang}                 //和{p 4 8 2}相同
{phang2}                //和{p 8 12 2}相同
{p_end}                 //表示段落结束

延用阶乘的例子,我们可以为 myfact3 命令编写帮助文件。在编写帮助文件时考虑到用户群体的不同,我们可以编写两个版本的帮助文件,一个是英文版的,命名为 myfact.sthlp ;另一个为中文版的,命名为 myfact3_Cn.sthlp 。如此一来,用户只需输入 help myfact 或者入 help myfact3_Cn 就可以查看不同版本的 myfact3 命令的帮助文件了。

以编写 myfact.sthlp 为例,代码如下:

{smcl}
{* 9 Dec 2020}{...}
{hline}
help for {hi:myfact}
{hline}

{title:Title}

{p 4 4 2}
{bf:myfact} —— Calculate Factorial of a Positive Integer

{title:Syntax}

{p 4 4 2}
{cmdab:myfact} {anything},
[
{cmdab:F:ormat:}{cmd:(}string{cmd:)}
]

{title:Description}

{p 4 4 2}
{cmd:myfact} makes it easy for users to calculate the factorial of a positive integer
and specify the format of the output.

{title:Options}

{p 4 4 2}{cmd:Format(}{it:string}{cmd:)} specifies the format of the output.

{title:Examples}

{p 4 4 2} *- Calculate 10!. {p_end}
{p 4 4 2}{inp:.} {stata `"myfact 10"'}{p_end}

{p 4 4 2} *- Calculate 10! and specify the format of the output {p_end}
{p 4 4 2}{inp:.} {stata `"myfact 10, format(%-20.0g)"'}{p_end}

{title:Author}

{p 4 4 2}
{cmd:Ying,Yu}{break}
Lingnan College, Sun Yat-Sen University.{break}
E-mail: {browse "mailto:yuying29@mail2.sysu.edu.cn":yuying29@mail2.sysu.edu.cn}. {break}

你可以新建一个空白的 dofile,把下面的代码贴入其中,另存为 myfact,保存类型为:.sthlp,即最终文档为 myfact.sthlp

输入 help myfact 可以得到:

Hint:

为了提高用户体验,可以考虑编写两个版本的帮助文件,一个为英文版的,一个为中文版;其次可以设置帮助文件中的超链接(显示为蓝色),用户点击即可自动帮用户在命令窗口输入代码。你可以使用 ssc install lianxh 安装,并进而使用 help lianxh 查看一下其帮助文件,上述两种效果都有呈现。

致谢: 多谢岭南学院康峻杰 ( help lianxh 命令的作者之一) 和邱枞同学在此部分的经验分享。

6. 命令的发布

你可以采用多种方式发布你的新命令:

  • ssc
  • github
  • gitee

6.1 通过 ssc 发布新命令

SSC 是 Stata 用户发布自编命令的主要平台,详情参见 help ssc ( [R] ssc )。连享会团队此前编写的 lianxh.ado 命令便是通过 SSC 发布的。连老师自编的 winsor2, ua, xtbalance 等命令也都是通过 SSC 发布的。

发布方法很简单:只需把 NewCommand.adoNewCommand.sthlp 发送给 Boston College 的 Baum C.F. 教授即可,邮箱:baum@bc.edu

有关 SSC 提交的一些说明参见:Submitting and retrieving materials from the SSC Archive

6.2 通过 github 和 gitee 发布新命令

对于测试阶段的程序,或者不想通过 SSC 发布的程序,可以通过自己的 Github 或 Gitee (码云) 账号来发布。你需要在自己的账号下新建一个与程序同名的仓库,将程序文件连同索引文件上传到该仓库下。随后便可告知其他人通过 help github 命令组检索、安装了。

例如,连老师团队编写的 lianxh.ado 命令的 Github 主页为 https://github.com/arlionn/lianxh。你可以看到,核心文件包括:

  • lianxh.ado
  • lianxh.sthlp
  • lianxh.pkg
  • stata.toc

也就是说,除了基本的 .ado.sthlp 文档外,你还需要编写 lianxh.pkgstata.toc 两个索引文档,以便告诉搜素引擎改程序组包括哪些程序文件、程序的基本信息等。这两个文档都是文本文件,你只需要在记事本中编写好上述文档,进而对照修改文件后缀即可。当然,你也可以使用外部命令 make (github-项目主页) 自动生成上述文件。最简单的办法就是从 https://github.com/arlionn/lianxh 复制 lianxh.pkgstata.toc 文档到本地,酌情修改文件名和文件内容即可。

下面分别是这两份文档中的基本内容,其中的标记符含义如下:

  • v 表示版本号 (version)
  • d 是 describe 的简写
  • f 是 file 的简写
  • p 是 program 的简写
---------------------lianxh.pkg----------------
v 2.17 
d `lianxh` 在 Stata 命令窗口中快速查询连享会发布的推文,获取 Stata 资源。
d Distribution-Date:   20201122
f lianxh.ado
f lianxh.sthlp
---------------------stata.toc----------------
v 2.17 
v 2.17
d Materials by 连玉君, 康峻杰, 刘庆庆
d arlionn@163.com
d https://gitee.com/arlionn/lianxh
d 'lianxh': `lianxh` 可以让你在 Stata 命令窗口中快速查询连享会发布的推文,获取 Stata 资源。
p lianxh

最后,需要说明的是:

  • 使用 github 或 gitee 发布的命令在 Stata 16 中安装时经常会出问题,主要与 Stata 16 的网络设置代码有关,目前尚未实质性解决;因此,相对于 ssc,这两种发布方式不是首选。
  • 使用 gitee 发布新命令,需要配合 net install 命令来安装,同时需要开启 gitee 的页面服务功能,详情参见 码云正式支持 Pages 功能

7. 进一步学习 ado 文件

要想进一步了解编写 ado 文件时使用的更高级的命令,可以参考 Stata 编程手册(Stata Programming Reference Manual)。同时,还可以阅读现有的 ado 文件并在自己的 ado 文件中借鉴前人的方法。以下有三种方法:

  • 使用 findfile 命令定位已有的 ado 文件
    findfile kappa.ado
    
  • 使用 viewsource 命令可以查看 ado 文档。
    viewsource kappa.ado
    
  • 使用 ssc type 命令来查看 SSC 上存档的所有 ado 文件。
    ssc type whitetst.ado
    

8. 相关推文

相关课程

连享会-直播课 上线了!
http://lianxh.duanshu.com

免费公开课:


课程一览

支持回看

专题 嘉宾 直播/回看视频
最新专题 因果推断, 空间计量,寒暑假班等
数据清洗系列 游万海 直播, 88 元,已上线
研究设计 连玉君 我的特斯拉-实证研究设计-幻灯片-
面板模型 连玉君 动态面板模型-幻灯片-
面板模型 连玉君 直击面板数据模型 [免费公开课,2小时]

Note: 部分课程的资料,PPT 等可以前往 连享会-直播课 主页查看,下载。


关于我们

  • Stata连享会 由中山大学连玉君老师团队创办,定期分享实证分析经验。直播间 有很多视频课程,可以随时观看。
  • 连享会-主页知乎专栏,300+ 推文,实证分析不再抓狂。
  • 公众号推文分类: 计量专题 | 分类推文 | 资源工具。推文分成 内生性 | 空间计量 | 时序面板 | 结果输出 | 交乘调节 五类,主流方法介绍一目了然:DID, RDD, IV, GMM, FE, Probit 等。
  • 公众号关键词搜索/回复 功能已经上线。大家可以在公众号左下角点击键盘图标,输入简要关键词,以便快速呈现历史推文,获取工具软件和数据下载。常见关键词:课程, 直播, 视频, 客服, 模型设定, 研究设计, stata, plus, 绘图, 编程, 面板, 论文重现, 可视化, RDD, DID, PSM, 合成控制法

连享会主页  lianxh.cn
连享会主页 lianxh.cn

连享会小程序:扫一扫,看推文,看视频……

扫码加入连享会微信群,提问交流更方便

✏ 连享会学习群-常见问题解答汇总:
https://gitee.com/arlionn/WD

New! lianxh 命令发布了:
随时搜索连享会推文、Stata 资源,安装命令如下:
. ssc install lianxh
使用详情参见帮助文件 (有惊喜):
. help lianxh