让我们逐行看这个。
local var year
var
您用 content定义了一个本地宏"year"
。这是合法的,但您从不在此代码中引用该本地宏,因此该定义毫无意义。
local j = 1996
j
您用 content定义了一个本地宏"1996"
。这是合法的。
foreach j of var year {
您打开一个循环并将循环索引定义为j
。这意味着在循环中对本地宏的任何引用j
都将根据您提供的参数列表进行解释。(前面的定义j
在循环中是不相关的,因此对你的其余代码没有影响。)
... of var year
您在此处指定循环在变量列表上。请注意,var
这里的关键字是缩写,与您刚刚定义varlist
的本地宏名称完全无关。var
变量列表由单个变量名组成year
。
gen d`j' = 1 if year==`j'
该语句将被解释为循环执行的唯一一次,如
gen dyear = 1 if year==year
因为对局部宏的引用j
被替换为它的内容,即变量名year
。year==year
对于每个观察都是正确的。效果是一个新变量dyear
,在每个观察中都是 1。这不是您想要的指标或虚拟变量。如果您仔细查看数据集,您会发现这不是year
1996 年的虚拟变量。
local ++j
您正在尝试将本地宏j
增加 1。但您只是将本地宏设置j
为包含字符串"year"
,这是一个变量名。但是您不能将 1 添加到字符串中,因此错误消息将为type mismatch
. 您没有报告该错误,这是一个惊喜。这有点微妙,因为在前面的命令中,上下文generate
允许将引用解释为year
使用变量 计算的指令,变量year
自然是数字。但是local
命令都是关于字符串操作的,它可能有也可能没有数字解释,你的命令首先等同于指示 Stata 添加
"year" + 1
这会触发类型不匹配错误。
远离你的代码:考虑一个循环
forval y = 1996/2012 {
gen d`y' = 1 if year == `y'
}
这更接近您想要的,但更清楚地说明了代码中的另一个错误。这将创建变量d1996
,d2012
但每个变量在指定的年份都为 1,否则会丢失,这不是您想要的。您可以通过在循环中添加另一行来解决此问题
replace d`y' = 0 if year != `y'
但更清洁的方法是单行
gen d`y' = year == `y'
表达方式
year == `y'
当为真时被评估为 1,当为假时被评估为 0,这就是你想要的。
所有这些都是在 [U] 或 [P] 中记录的标准技术。
然而,正如@Roberto Ferrer 指出的那样,有经验的 Stata 用户不会以这种方式定义假人,因为tabulate
它提供了一个选项,可以在没有循环的情况下进行。
http://www.stata-journal.com/sjpdf.html?articlenum=pr0005中汇集了对本地宏foreach
和forvalues
循环的评论的教程
search foreach
在 Stata 中会指出这是您可以阅读的各种作品之一。