For loop 在Stata中使用for循环(foreach)计算年份虚拟变量

For loop 在Stata中使用for循环(foreach)计算年份虚拟变量,for-loop,stata,dummy-data,For Loop,Stata,Dummy Data,我正在尝试为1996年至2012年(含)的每年生成一个虚拟变量,以便1996年的虚拟变量应等于1(如果是1996年),如果是0(如果是),则使用Stata中的foreach命令至少为未来项目缩短时间。目前正在发生的事情是,1996年的假人正在生产,但没有其他的生成。 我认为这与我如何定义j有关,但我不能完全理解实现我想要的结果的格式。我在网上和Stata帮助文件中查找过,但找不到有关此特定主题的任何内容 以下是我迄今为止所做的: local var year local j = 1996 for

我正在尝试为1996年至2012年(含)的每年生成一个虚拟变量,以便1996年的虚拟变量应等于1(如果是1996年),如果是0(如果是),则使用Stata中的foreach命令至少为未来项目缩短时间。目前正在发生的事情是,1996年的假人正在生产,但没有其他的生成。 我认为这与我如何定义j有关,但我不能完全理解实现我想要的结果的格式。我在网上和Stata帮助文件中查找过,但找不到有关此特定主题的任何内容

以下是我迄今为止所做的:

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

我将继续尝试自己解决这个问题,但如果有人提出建议,我将不胜感激。

不需要循环。使用gen选项尝试tablate命令。请参见帮助单程列表

也请参阅帮助席和帮助变量。


您正试图循环遍历年份的不同值,但语法不正确。实际上,您正在循环一系列变量,其中只有一个元素:year。命令levelsof提供了不同的值,但正如我所说的,循环是不必要的

不需要循环。使用gen选项尝试tablate命令。请参见帮助单程列表

也请参阅帮助席和帮助变量。


您正试图循环遍历年份的不同值,但语法不正确。实际上,您正在循环一系列变量,其中只有一个元素:year。命令levelsof提供了不同的值,但正如我所说的,循环是不必要的

让我们一行一行地看一下

local var year
您使用内容年定义了本地宏变量。这是合法的,但您在代码中从不引用该本地宏,因此定义是毫无意义的

local j = 1996
您使用content 1996定义了一个本地宏j。这是合法的

foreach j of var year {
打开一个循环并将循环索引定义为j。这意味着在循环中,对本地宏j的任何引用都将根据您提供的参数列表进行解释。前面对j的定义在循环中是不相关的,因此对代码的其余部分没有影响

... of var year 
您可以在此处指定循环在变量列表上。请注意,这里的关键字var是varlist的缩写,与刚才定义的本地宏名称var完全无关。变量列表由单个变量名称年份组成

此语句将被解释,也是唯一一次执行循环,如下所示

gen dyear = 1 if year==year 
当对本地宏j的引用被其内容替换时,变量名year。年==年对每个观察都是正确的。该效应是一个新变量,在每次观测中为1。这不是您想要的指示符或虚拟变量。若你们仔细查看你们的数据集,你们会发现这并不是1996年的一个虚拟变量

local ++j
您正试图将本地宏j增加1。但您只需将局部宏j设置为包含字符串year,这是一个变量名。但是不能将1添加到字符串中,因此错误消息将是类型不匹配。你没有报告这个错误,这是一个惊喜。这有点微妙,因为在前面的命令中,generate的上下文允许将对year的引用解释为使用变量year进行计算的指令,该变量自然是数字。但是本地命令都是关于字符串操作的,它可能有数字解释,也可能没有数字解释。首先,您的命令相当于指示Stata添加

"year" + 1 
这会触发类型不匹配错误

远离代码:考虑循环

forval y = 1996/2012 { 
    gen d`y' = 1 if year == `y'
} 
这更接近您想要的,但更清楚地说明了代码中的另一个bug。这将创建变量d1996到d2012,但在指定的年份中,每个变量都将是1,否则将丢失,这不是您想要的。 您可以通过在循环中再添加一行来修复此问题

    replace d`y' = 0 if year != `y' 
但是一个更干净的方法是单行线

    gen d`y' = year == `y' 
表情

               year == `y' 
为真时计算为1,为假时计算为0,这是您想要的

所有这些都是[U]或[p]中记录的标准技术

然而,正如@Roberto Ferrer所指出的,有经验的Stata用户不会以这种方式定义假人,因为tablate提供了一种不用循环的选项

内有一个教程,其中汇集了有关本地宏、foreach和forvalues循环的注释


在斯塔塔看来,这是你可以阅读的众多作品之一

让我们一行一行地看一下

local var year
您使用内容年定义了本地宏变量。这是合法的,但您在代码中从不引用该本地宏,因此定义是毫无意义的

local j = 1996
您使用content 1996定义了一个本地宏j。这是合法的

foreach j of var year {
打开一个循环并将循环索引定义为j。这意味着在循环中,对本地宏j的任何引用都将根据 你提供的论点。前面对j的定义在循环中是不相关的,因此对代码的其余部分没有影响

... of var year 
您可以在此处指定循环在变量列表上。请注意,这里的关键字var是varlist的缩写,与刚才定义的本地宏名称var完全无关。变量列表由单个变量名称年份组成

此语句将被解释,也是唯一一次执行循环,如下所示

gen dyear = 1 if year==year 
当对本地宏j的引用被其内容替换时,变量名year。年==年对每个观察都是正确的。该效应是一个新变量,在每次观测中为1。这不是您想要的指示符或虚拟变量。若你们仔细查看你们的数据集,你们会发现这并不是1996年的一个虚拟变量

local ++j
您正试图将本地宏j增加1。但您只需将局部宏j设置为包含字符串year,这是一个变量名。但是不能将1添加到字符串中,因此错误消息将是类型不匹配。你没有报告这个错误,这是一个惊喜。这有点微妙,因为在前面的命令中,generate的上下文允许将对year的引用解释为使用变量year进行计算的指令,该变量自然是数字。但是本地命令都是关于字符串操作的,它可能有数字解释,也可能没有数字解释。首先,您的命令相当于指示Stata添加

"year" + 1 
这会触发类型不匹配错误

远离代码:考虑循环

forval y = 1996/2012 { 
    gen d`y' = 1 if year == `y'
} 
这更接近您想要的,但更清楚地说明了代码中的另一个bug。这将创建变量d1996到d2012,但在指定的年份中,每个变量都将是1,否则将丢失,这不是您想要的。 您可以通过在循环中再添加一行来修复此问题

    replace d`y' = 0 if year != `y' 
但是一个更干净的方法是单行线

    gen d`y' = year == `y' 
表情

               year == `y' 
为真时计算为1,为假时计算为0,这是您想要的

所有这些都是[U]或[p]中记录的标准技术

然而,正如@Roberto Ferrer所指出的,有经验的Stata用户不会以这种方式定义假人,因为tablate提供了一种不用循环的选项

内有一个教程,其中汇集了有关本地宏、foreach和forvalues循环的注释

在斯塔塔看来,这是你可以阅读的众多作品之一

也许这会有帮助

/*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' 
}

然而,我同意Roberto Ferrer的观点,循环可能不是必需的。

也许这会有所帮助

/*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' 
}


然而,我同意Roberto Ferrer的观点,环可能没有必要。

非常好的解剖。谢谢!这真的很有帮助,肯定会提高我对循环的理解,即使这次没有必要。非常好的解剖。谢谢!这真的很有帮助,肯定会提高我对循环的理解,即使这次没有必要。谢谢!这绝对是一种更有效的方法。谢谢!这绝对是一种更有效的方法。循环中的两行可以减少为一行,正如我在回答中所解释的。fyear后面的空格应该去掉;否则这些命令是非法的。循环中的两行可以减少为一行,正如我在回答中所解释的。fyear后面的空格应该去掉;否则,这些命令是非法的。