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 yourname
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).
精彩评论