
宏(Macro)是STATA程序中很重要的概念,主要用来在循环语句中对一系列变量名称或者数字进行替代,从而减少机械重复。在这些基础用法之外,STATA提供了一些宏的函数,来增强宏的功能。本文将对其中两类宏函数进行举例介绍。
所有宏函数的语法格式是一致的: localmacro:function,即在定义好宏的名字之后的冒号后使用函数。下面我们具体介绍两类函数,一类是 word i of,用来处理平行列表,一类是 varlabel,用来提取变量标签。
word i of)我们处理数据时会遇到需要使用两列平行的变量的情况。用STATA的auto.dta来举例,我们需要对不同变量进行tabulate,而每组变量的限制条件也不相同:
sysuse auto,clear
sum make        if rep78 > 0
sum gear_ratio  if rep78 > 2
sum mpg         if rep78 > 5当每列变量从三个增加到三十个甚至更多时,上述代码就会变得异常臃肿。这时,平行列表结合宏函数 word i of可以简洁的解决这个问题。平行列表即是两个宏变量:
local thresholdlist "0 2 5"
local varlist "make gear_ratio mpg"word i of函数可以选取一个列表中的第 i个值,该值可以是数字或者文字。将平行列表和 word i of函数结合之后,我们就可以轻松的处理任意数量的该类型问题。
sysuse auto,clear
local thresholdlist "0 2 5"
local varlist "headroom gear_ratio mpg"
local numitems = wordcount("`thresholdlist'")
forvalues i=1/`numitems' {
    local thisthreshold : word `i' of `thresholdlist'
    local thisvar : word `i' of `varlist'
    di "variable: `thisvar', threshold: `thisthreshold'"
    sum `thisvar'  if rep78 > `thisthreshold'
}
varlabel第二种函数是 varlabel,用来提取变量的标签。该函数的应用场景非常广泛,我们举一个例子说明。假设有如下数据

该数据由以下代码生成
ssc install dataex
clear
input companyid str10 product
1 "P2P"
2 "Retail"
3 "Commercial"
4 "CreditCard"
5 "CreditCard"
6 "EMFunds"
end当我们希望生成一个代表产品的时,我们可以输入:
tab product,gen(productID)
问题来了,上述代码生成的变量名称是productID1,productID2等,如果我们希望用产品的内容来命名每个变量该如何实现呢?下面我们介绍一种使用 varlabel函数来实现的方法,具体代码如下:
ds product_id*
foreach var of varlist `r(varlist)' {
    local varlabel: variable label `var'
    display "`varlabel'"
    local pos = strpos("`varlabel'","==")+2
    local varlabel = substr("`varlabel'",`pos',.)
    display "`varlabel'"
    rename `var' `varlabel'
}具体来说:
ds product_id 是把所有刚才生成的产品变量名称放到一个叫做 r(varlist)的宏里,用于下面语句的循环。r(varlist) 用来循环每一个产品变量。variable lable 函数来提取每个产品变量的label,例如productID1变量的label是 product==P2P。这样,我们就可以把"product==P2P"提取到一个名为 varlabel的宏中strpos 和 substr函数来提取label中我们需要的部分,例如对productID1,我们只需要"P2P"字符。最后的效果如图:
