开发者

foreach loop odd behavior

I'm getting odd behavior (it generates only missing values) from the following loop -

foreach x of varlist name {   
    egen totalcap`x' = total(cap) if unit!=0 & name=="`x'", by(year)   
}

But if I were to do just

egen totalcapSOMENAME=total(cap) if unit!=0 & name=="SOMENAME", by(year)

then it computes the numbers that it's supposed to compute.

This is a panel dataset, unit denotes number within a powerplant of a part开发者_如何学JAVAicular generator unit (units numbered 0 are plant-level observations). The cap variable is installed capacity. The name variable identifies the plant. It's complicated to explain why I need this loop, but the problem is clearly with the way Stata interprets foreach.


You've got a couple of issues here. Most importantly, your first loop is evaluating the word name in place of x throughout your loop. So it is running your egen command as:

foreach x of varlist name {
     egen totalcapname = total(cap) if unit!=0 and name=="name", by(year)
}

I doubt this is what you really want--I think you want it to evaluate by each item (observation) in your name variable since you used the if condition

name=="`x'"  

So, you need to

  • get rid of the double quotes around the macro reference in your if condition

OR

  • set up a local macro and set the egen loop to evaluate for each item in your name variable.

The second error I see in your code is that you are missing the forward or left quote for the x in the loop--it should read

"`x'"`   

not

"x'"

Here is an example of what I THINK you want to run. For illustration purposes, I am using the Stata in-built "auto.dta" dataset to run your loop & standalone egen statement...please note that I rename the variables in the auto.dta to the names of your variables:

***********
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)
***********

Try running this example in a Stata do-file. Also, when you have these sort of issues (where the loop creates a different outcome than the stand alone command), always try typing set trace on so that you can see how Stata is evaluating your loop.


Although the answer above was accepted (almost 11 years ago) there is a misunderstanding in the question that is both frequent and deserving of a little more emphasis than in @eric.a.booth's helpful answer.

The misunderstanding is that

foreach x of varlist name 

is somehow automatically a loop over the distinct (some say "unique", but that is not a good term in my view) values of the variable name. Other software may do that for you but it's in no sense what Stata promises with foreach. That is a loop over precisely one item, the single variable name in the supplied varlist. As such it's overkill as you could just type the statement(s) inside the loop, but Stata naturally doesn't forbid a varlist with just one name or using such in foreach.

In this particular case,

egen totalcap = total(cap) if unit!=0, by(name year) 

would put all the totals of interest in a single variable and if you preferred that to go in several variables, then use separate to do that without a loop (or more precisely, separate uses a loop, but it is within the code).

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜