Stata编程:暂元local和global的使用技巧

发布时间:2022-11-24 阅读 3595

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

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

New! lianxh 命令发布了:
随时搜索推文、Stata 资源。安装:
. ssc install lianxh
详情参见帮助文件 (有惊喜):
. help lianxh
连享会新命令:cnssc, ihelp, rdbalance, gitee, installpkg

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

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

⛳ Stata 系列推文:

PDF下载 - 推文合集

作者:陈云菲 (上海大学)
邮箱cyfyeya17863928515@163.com

编者按:本文主要参考自下文,特此致谢!

  • Cox N J. Stata tip 138: Local macros have local scope[J]. The Stata Journal, 2020, 20(2): 499-503. -PDF-
  • Herrin J. Stata tip 77:(Re) using macros in multiple do-files[J]. The Stata Journal, 2009, 9(3): 497-498. -PDF-


目录


在使用 Stata 运算时,每个人或多或少都曾遇到过变量繁多、程序复杂,让人眼花缭乱,以及不断做重复性步骤,降低工作效率。其实,Stata 中的暂元 (macros) 以有效解决这些问题。接下来,我们将从暂元 (macros) 的定义、种类、使用技巧和注意事项等几个方面做一个梳理,以帮助大家快速了解暂元。

1. 暂元的定义

暂元 (macros),顾名思义可解释成“暂时的元素”。暂元就像一个“盒子”,我们可以把需要的内容放进不同的“盒子” (暂元 macros) 里,然后做好标记 (给每一个暂元 macros 取一个新的名字),运行命令时直接调用“盒子”的名字,Stata 就可以自动识别并提取。“盒子”里的内容可以是字符串、数字、变量、返回值,甚至可以是暂元 (macros)。

2. 暂元 (macros) 家族

全局暂元 (global macros):“永久性盒子”,在 Stata 关闭之前将一直存在。局部暂元 (local macros):“一次性盒子”,每一次使用都需要重新定义,并且只在选中的局部代码块中有效。运行包含局部暂元 (local) 的多行命令时,需要同时执行,否则会报错。

全局暂元 (global) 和局部暂元 (local) 二者互有优劣,include 命令可以结合二者的优势。本文将从这三个部分出发,揭开暂元 (macros) 神秘的面纱。

3. 暂元 (macros) 使用技巧

3.1 全局暂元 (global macros)

作为永久性盒子,全局暂元 (global macros) 一旦被定义,那么就可以在全局被调用,包括:

  • 直接在命令窗口中输入命令
  • 运行整个 do 文件或 do 文件中的某段代码
  • 编写的程序 (program)

定义全局暂元 (global) 的基本命令为:

global name "value"

其中,name 为全局暂元 (global) 的名称,value 为全局暂元 (global) 储存的内容。调用全局暂元 (global) 的命令为 $暂元名称。下面我们运用 Stata 自带的 1978 汽车数据集 auto.dta 来检验此命令。

. sysuse auto, clear
. * 将表示汽车特征的一组变量放入全局暂元 size 中
. global size " weight length trunk displacement "
. regress price $size

      Source |       SS           df       MS      Number of obs   =        74
-------------+----------------------------------   F(4, 69)        =      9.22
       Model |   221276728         4  55319182.1   Prob > F        =    0.0000
    Residual |   413788668        69  5996937.22   R-squared       =    0.3484
-------------+----------------------------------   Adj R-squared   =    0.3107
       Total |   635065396        73  8699525.97   Root MSE        =    2448.9
------------------------------------------------------------------------------
       price | Coefficient  Std. err.      t    P>|t|     [95% conf. interval]
-------------+----------------------------------------------------------------
      weight |      4.649      1.412     3.29   0.002        1.831       7.466
      length |   -102.309     43.083    -2.37   0.020     -188.259     -16.360
       trunk |     27.899     97.905     0.28   0.777     -167.416     223.215
displacement |      0.616      7.026     0.09   0.930      -13.401      14.633
       _cons |  10850.978   4628.016     2.34   0.022     1618.338   20083.619
------------------------------------------------------------------------------

当 Stata 看到 $size 时,将会把“盒子”里的内容替换到命令中,最后输出结果。因此,Stata 实际运行的命令是 regress price weight length trunk displacement。再举一个将命令返回值存储到全局暂元 (global) 中的例子,假设我们想要得到变量的中位数,我们可以这样做:

. sum price, detail
                            Price
-------------------------------------------------------------
      Percentiles      Smallest
 1%         3291           3291
 5%         3748           3299
10%         3895           3667       Obs                  74
25%         4195           3748       Sum of wgt.          74

50%       5006.5                      Mean           6165.257
                        Largest       Std. dev.      2949.496
75%         6342          13466
90%        11385          13594       Variance        8699526
95%        13466          14500       Skewness       1.653434
99%        15906          15906       Kurtosis       4.819188

. * 将中位数的值存储到全局暂元 median_price 中
. global median_price = r(p50) 
. display "$median_price"
5006.5

作为一个“盒子”,如果将里面的内容替换掉,当 Stata 再次调用它的时候也会自动更新。听起来似乎不错,但全局暂元 (global) 全局有效的特点,有时候会导致严重错误。如果替换“盒子”里面的内容,可能会导致调用相同名字但存放内容不同的暂元出现问题。为避免这种错误,定义太多不同名字的暂元又会造成另一种复杂性。局部暂元 (local) 的出现弥补了这种不足。

3.1 局部暂元 (local macros)

作为一次性盒子,局部暂元 (local macros) 在 do 文件中只能执行一次,执行过后会释放暂元内容,下次使用时需要重新定义,并且在其他的 do 文档或者同一 do 文档其他代码块中无法识别。定义局部暂元 (local) 的基本命令为:

local name "value"

其中,name 为局部暂元 (local) 的名称,value 为局部暂元 (local) 储存的内容。调用局部暂元 (local) 的命令为 `暂元名称'。其中,左侧为 Tab 键上方反引号,右侧为 Enter 键左边单引号。以 1978 汽车数据集 auto.dta 为例:

. sysuse auto, clear
. local size "weight length trunk displacement" // 定义局部暂元 size
. regress price `size'                          // 回归分析

      Source |       SS           df       MS      Number of obs   =        74
-------------+----------------------------------   F(4, 69)        =      9.22
       Model |   221276728         4  55319182.1   Prob > F        =    0.0000
    Residual |   413788668        69  5996937.22   R-squared       =    0.3484
-------------+----------------------------------   Adj R-squared   =    0.3107
       Total |   635065396        73  8699525.97   Root MSE        =    2448.9
------------------------------------------------------------------------------
       price | Coefficient  Std. err.      t    P>|t|     [95% conf. interval]
-------------+----------------------------------------------------------------
      weight |      4.649      1.412     3.29   0.002        1.831       7.466
      length |   -102.309     43.083    -2.37   0.020     -188.259     -16.360
       trunk |     27.899     97.905     0.28   0.777     -167.416     223.215
displacement |      0.616      7.026     0.09   0.930      -13.401      14.633
       _cons |  10850.978   4628.016     2.34   0.022     1618.338   20083.619
------------------------------------------------------------------------------

再次强调,运行包含局部暂元的多行命令时,需要同时选中执行该代码块,否则会失效或报错。比如,我们先运行定义局部暂元的命令,然后再运行回归命令。

. local size "weight length trunk displacement" // 先运行这一行命令
. regress price `size'                          // 再运行这一行命令

      Source |       SS           df       MS      Number of obs   =        74
-------------+----------------------------------   F(4, 69)        =      9.22
       Model |   221276728         4  55319182.1   Prob > F        =    0.0000
    Residual |   413788668        69  5996937.22   R-squared       =    0.3484
-------------+----------------------------------   Adj R-squared   =    0.3107
       Total |   635065396        73  8699525.97   Root MSE        =    2448.9
------------------------------------------------------------------------------
       price | Coefficient  Std. err.      t    P>|t|     [95% conf. interval]
-------------+----------------------------------------------------------------
      weight |      4.649      1.412     3.29   0.002        1.831       7.466
      length |   -102.309     43.083    -2.37   0.020     -188.259     -16.360
       trunk |     27.899     97.905     0.28   0.777     -167.416     223.215
displacement |      0.616      7.026     0.09   0.930      -13.401      14.633
       _cons |  10850.978   4628.016     2.34   0.022     1618.338   20083.619
------------------------------------------------------------------------------

此时,局部暂元已经失效,在 Stata 中相当于命令 regress price,即汽车价格对常数项进行回归。尽管有了全局暂元 (global) 和局部暂元 (local),有研究者提出了新的问题:如果只想在某几个 do 文件里面使用暂元,并非永久的全局性也非临时的局部性,怎么办呢?Stata 中提供了 include 命令来解决这个问题。

3.3 取长补短的 include 命令

include 命令可以实现将指定的 do 文件内容插入命令行位置以取代该命令行,从而将指定的文件和当前的源程序文件连成一个源文件。include 命令的调用方法 include "文件名"。下面我们仍然运用 Stata 自带的 1978 汽车数据集 auto.dta 来检验此命令。

首先,我们建立一个 do 文件,命名为 locals.do,并在该 do 文件中定义 size1size2 两个局部暂元。

* 生成 locals.do 文件,并保存
local size1 " weight length "
local size2 " trunk displacement "

然后,利用 include 命令调用上述暂元。

. sysuse auto, clear 
. include locals.do

. local size1 " weight length "
. local size2 " trunk displacement "

. regress price `size1' `size2'

      Source |       SS           df       MS      Number of obs   =        74
-------------+----------------------------------   F(4, 69)        =      9.22
       Model |   221276728         4  55319182.1   Prob > F        =    0.0000
    Residual |   413788668        69  5996937.22   R-squared       =    0.3484
-------------+----------------------------------   Adj R-squared   =    0.3107
       Total |   635065396        73  8699525.97   Root MSE        =    2448.9
------------------------------------------------------------------------------
       price | Coefficient  Std. err.      t    P>|t|     [95% conf. interval]
-------------+----------------------------------------------------------------
      weight |      4.649      1.412     3.29   0.002        1.831       7.466
      length |   -102.309     43.083    -2.37   0.020     -188.259     -16.360
       trunk |     27.899     97.905     0.28   0.777     -167.416     223.215
displacement |      0.616      7.026     0.09   0.930      -13.401      14.633
       _cons |  10850.978   4628.016     2.34   0.022     1618.338   20083.619
------------------------------------------------------------------------------

如果想要修改内容,直接在 locals.do 中进行修改,再次调用时,Stata 会读取新的内容。在程序设计中,include 命令非常有用,将一些常用的符号或变量单独命名成一个 do 文件,避免每次都重新编写,节省时间,并减少出错。因此,include 实现了可以在多个 do 文件中同时调用不同全局暂元 (global) 和局部暂元 (local) 功能。

4. 相关推文

Note:产生如下推文列表的 Stata 命令为:
lianxh 暂元 循环, m
安装最新版 lianxh 命令:
ssc install lianxh, replace

相关课程

免费公开课

最新课程-直播课

专题 嘉宾 直播/回看视频
最新专题 文本分析、机器学习、效率专题、生存分析等
研究设计 连玉君 我的特斯拉-实证研究设计-幻灯片-
面板模型 连玉君 动态面板模型-幻灯片-
面板模型 连玉君 直击面板数据模型 [免费公开课,2小时]
  • Note: 部分课程的资料,PPT 等可以前往 连享会-直播课 主页查看,下载。

课程主页

课程主页

关于我们

  • Stata连享会 由中山大学连玉君老师团队创办,定期分享实证分析经验。
  • 连享会-主页知乎专栏,700+ 推文,实证分析不再抓狂。直播间 有很多视频课程,可以随时观看。
  • 公众号关键词搜索/回复 功能已经上线。大家可以在公众号左下角点击键盘图标,输入简要关键词,以便快速呈现历史推文,获取工具软件和数据下载。常见关键词:课程, 直播, 视频, 客服, 模型设定, 研究设计, stata, plus, 绘图, 编程, 面板, 论文重现, 可视化, RDD, DID, PSM, 合成控制法

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

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

✏ 连享会-常见问题解答:
https://gitee.com/lianxh/Course/wikis

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