使用Stata中的for循环(foreach)计算年虚拟变量

时间:2014-05-02 21:34:30

标签: for-loop stata dummy-data

我试图从1996年到2012年(包括)每年生成一个虚拟变量,这样1996年的假人在1996年时应该等于1,如果在Stata中使用foreach命令则减少0准时(至少为未来的项目)。目前正在发生的是1996年的假人正在制作,但没有其他人产生。 我认为它与我如何定义j有关,但我无法弄清楚格式化以实现我想要的结果。我已经在线查看了Stata帮助文件,但在这个特定主题上找不到任何内容。

这是我到目前为止所做的:

local var year
local j = 1996
foreach j of var year {
    gen d`j' = 1 if year==`j'
    local ++j
}

我将继续尝试自己解决这个问题,但如果有人有建议我会非常感激。

3 个答案:

答案 0 :(得分:4)

让我们逐行看一下。

local var year

您定义了内容为var的本地宏"year"。这是合法的,但您从未在此代码中引用该本地宏,因此该定义毫无意义。

local j = 1996

您定义了内容为j的本地宏"1996"。这是合法的。

foreach j of var year {

打开循环并将循环索引定义为j。这意味着在循环内,对本地宏j的任何引用都将根据您提供的参数列表进行解释。 (j的先前定义在循环中是无关紧要的,因此对代码的其余部分没有影响。)

... of var year 

您可以在此指定循环在变量列表上。请注意,此处的关键字varvarlist的缩写,并且完全没有与您刚定义的本地宏名称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'
} 

这更接近你想要的,但更清楚你的代码中的另一个错误。这会创建变量d1996d2012但是在指定的年份中每个变量都是1,否则会丢失,这不是您想要的。 您可以通过在循环中添加更多行来解决此问题

    replace d`y' = 0 if year != `y' 

但更清洁的方法是单行

    gen d`y' = year == `y' 

表达式

               year == `y' 

在为true时评估为1,在false时评估为0,这是您想要的。

所有这些都是[U]或[P]中记载的标准技术。

正如@Roberto Ferrer指出的那样,有经验的Stata用户不会以这种方式定义假人,因为tabulate提供了一个没有循环的选项。

将本地宏foreachforvalues循环的评论汇集在一起​​的教程在http://www.stata-journal.com/sjpdf.html?articlenum=pr0005

之内
 search foreach 
Stata内部会指出这是你可以阅读的各种作品之一。

答案 1 :(得分:2)

不需要循环。使用tabulate选项尝试gen()命令。见help tabulate oneway

另请参阅help xihelp factor variables

您正在尝试遍历year的不同值,但语法不正确。实际上,您只使用一个元素循环遍历变量列表:year。命令levelsof为您提供了不同的值,但就像我说的那样,循环不是必需的。

答案 2 :(得分:0)

也许这可能会有所帮助。

/*assuming the data is from 1970-2012*/
/*assuming your year variable name is fyear*/

forvalues x=1970/2012 {  
gen fyear `x'=0
replace fyear `x'=1 if fyear==`x' 

}

但是,我确实同意罗伯托·费雷尔认为循环可能没有必要。