Loops foreach循环奇数行为
我从下面的循环中得到了奇怪的行为(它只生成缺少的值)-Loops foreach循环奇数行为,loops,foreach,stata,Loops,Foreach,Stata,我从下面的循环中得到了奇怪的行为(它只生成缺少的值)- foreach x of varlist name { egen totalcap`x' = total(cap) if unit!=0 & name=="`x'", by(year) } 但如果我只是 egen totalcapSOMENAME=total(cap) if unit!=0 & name=="SOMENAME", by(year) 然后它计算出它
foreach x of varlist name {
egen totalcap`x' = total(cap) if unit!=0 & name=="`x'", by(year)
}
但如果我只是
egen totalcapSOMENAME=total(cap) if unit!=0 & name=="SOMENAME", by(year)
然后它计算出它应该计算的数字
这是一个面板数据集,
unit
表示特定发电机组的动力装置内的编号(编号为0的装置为电厂级观测值)。cap
变量是装机容量。name
变量标识设备。解释我为什么需要这个循环很复杂,但问题显然在于Stata解释foreach的方式。最重要的是,您的第一个循环是在整个循环中计算单词name
,而不是x
。因此,它以如下方式运行您的egen
命令:
foreach x of varlist name {
egen totalcapname = total(cap) if unit!=0 and name=="name", by(year)
}
我怀疑这是您真正想要的——我想您希望它通过name
变量中的每个项目(观察值)进行评估,因为您使用了if
条件
name=="`x'"
所以,你需要
- 在
条件中,去掉宏引用周围的双引号if
- 设置一个本地宏,并设置
循环,以便为egen
变量中的每个项目求值name
x
的前引号或左引号,应该是
"`x'"`
不是
下面是一个我认为你想要运行的示例。出于说明目的,我使用Stata内置的“auto.dta”数据集运行循环和独立egen
语句…请注意,我将auto.dta中的变量重命名为变量名称:
***********
clear
sysuse auto
**
//this section renames the auto.dta variables to the name of your variables//
gen year = [_n]
rename mpg cap
rename price unit
rename make name
**NOTE: your "SOMENAME" will be "Subaru" in this example!**
**
//here's the loop you should be running//
foreach x of varlist name {
egen totalcap`x'=total(cap) if unit!=0 & name==`x', by(year)
}
//without the loop//
egen totalcapSOMENAME=total(cap) if unit!=0 & name=="Subaru", by(year)
//Display the results//
li name unit cap totalcap* if !missing(totalcapSOMENAME)
***********
尝试在Stata do文件中运行此示例。此外,当您遇到此类问题(循环产生的结果与独立命令不同)时,请始终尝试键入
set trace on
,以便查看Stata是如何评估您的循环的。尽管上述答案已被接受(大约11年前)这个问题中有一个误解,这个误解比@eric.a.booth的有用答案更为频繁,也更值得强调一点
误解是
foreach x of varlist name
在变量name
的不同(有人说“unique”,但在我看来这不是一个好术语)值上自动循环。其他软件可能会为您做到这一点,但这与Stata在foreach
中承诺的完全不同。这是一个循环,正好覆盖一个项,即提供的varlist中的单个变量名。因此,只需在循环中键入语句就太过分了,但Stata自然不会禁止只有一个名称的varlist或在foreach
中使用这样的语句
在这种特殊情况下
egen totalcap = total(cap) if unit!=0, by(name year)
将所有感兴趣的总计放在一个变量中,如果您希望将其放在多个变量中,则使用
分离来完成此操作,而不使用循环(或者更准确地说,分离使用循环,但它在代码中)。我忘记强调一件事(但包含在我提供的代码片段中)--在循环中,不需要在x周围使用双引号,只需要单引号……因此它应该是==`x',而不是===“x”。
egen totalcap = total(cap) if unit!=0, by(name year)