Stata The Stata listserver
[Date Prev][Date Next][Thread Prev][Thread Next][Date index][Thread index]

st: RE: levels for varlist? (sequel)


From   "Nick Cox" <n.j.cox@durham.ac.uk>
To   <statalist@hsphsun2.harvard.edu>
Subject   st: RE: levels for varlist? (sequel)
Date   Wed, 24 Sep 2003 10:26:08 +0100

Danielle H. Ferry wrote 
> > 
> > Is there a command similar to -levels- that works across 
> a varlist?
> > Specifically, suppose I have the variables highrisk1, 
> > highrisk2, lowrisk1,
> > lowrisk2, lowrisk3. I want to write a program with a loop 
> that does
> > something when highrisk==1, then when highrisk2==1, then 
> > when lowrisk1==1,
> > then when lowrisk2==1, and finally when lowrisk3==1. For example:
> > 
> > -----------------------------
> > program define example
> > 
> >     forval i = 1(1)2 {
> >      ta year if `1'`i'==1
> >     }
> > 
> > end
> > 
> > example highrisk
> > example lowrisk
> > -----------------------------
> > 
> > Since there are 2 highrisk variables and 3 lowrisk 
> > variables, the way I've
> > written it, this will miss tabulating when lowrisk3==1. If 
> > I make the second
> > line: "forval i = 1(1)3 {" then Stata will object when it gets to
> > "highrisk3==1" since highrisk3 doesn't exist. Something 
> > similar to -levels-
> > would enable Stata to figure out what the max on `i' should be.
> > 

and I replied 
 
> Two quick answers:
> 
> 1. Yes, but 
> 
> 2. You don't need one for this problem, 
> for which other approaches are better. 
> 
> In more detail, 
> 
> 2. 
> 
> foreach v of var highrisk* lowrisk* { 
> 	tab year if `v' == 1 
> } 
> 
> That is, you let -foreach- unpack the varlist 
> with which it is supplied. 
> 
> (Perhaps there is a neater wildcard, e.g. *risk*) 
> 
> 1. You could do this 
> 
> unab varlist : highrisk* lowrisk* 
> 
> foreach v of local varlist { 
> 	tab year if `v' == 1 
> } 
> 
> No apparent advantages here, but often useful 
> elsewhere. 
> 
> Similarly, you could do this 
> 
> ds highrisk* lowrisk* 
> 
> foreach v in `r(varlist)' { 
> 	tab year if `v' == 1 
> } 
> 
> Similar comment. Note especially 
> various filters which can be added 
> to -ds-. (Update 17 June 2003) 

I would like to expand this reply making two further
points. 

First, the intent of -levels- was to provide -- for 
categorical variables, wide sense -- a way of getting 
a value list, which is fairly often required for 
some problems, especially when commands do not work 
with -by:-. This was, in some ways, motivated by 
the parallel with the several ways which Stata 
provides (and has long provided) for working through varlists. 

Second, suppose that Danielle's problem had been 
a step more complicated, involving a loop 
over variables and also one over the possible 
values of those variables. 

foreach v of var highrisk* lowrisk* { 
	levels `v', local(levels) 
	foreach l of local levels { 
	 	tab year if `v' == `l'
	} 
} 

would then be one way of doing it. But 
in this example, as in many others, a
better way would be 

foreach v of var highrisk* lowrisk* { 
	bysort `v': tab year 
} 

The main reason for using -levels- is 
because you can't do something using -by:-. 

A secondary reason would be to tinker 
with the way that results are presented 
group by group. With -by:- there is not 
much flexibility in this regard (in 
fact, none, so far as I can see). Results
come separated by a dividing line and 
with an arrow, varname = value, etc., regardless. 
Being able to tune that, as a small but 
sometimes desirable detail, has been 
suggested to Stata Corp. With the do-it-yourself
approach of -levels-, quite how you separate
and label groups is up to you, typically 
as part of the -foreach- loop driving 
a cycling over groups. 

Nick
n.j.cox@durham.ac.uk 

*
*   For searches and help try:
*   http://www.stata.com/support/faqs/res/findit.html
*   http://www.stata.com/support/statalist/faq
*   http://www.ats.ucla.edu/stat/stata/



© Copyright 1996–2021 StataCorp LLC   |   Terms of use   |   Privacy   |   Contact us   |   What's new   |   Site index