Statalist The Stata Listserver


[Date Prev][Date Next][Thread Prev][Thread Next][Date index][Thread index]

Re: st: Using foreach to loop over macros


From   n j cox <n.j.cox@durham.ac.uk>
To   statalist@hsphsun2.harvard.edu
Subject   Re: st: Using foreach to loop over macros
Date   Tue, 22 Aug 2006 20:14:14 +0100

Your main idea is good. You just have illegal syntax.

First, a warning. With statements like

local nv1 = "v1 v3 v5 v11"

you run a risk of being bitten by a limit on the
length of a string expression that is being
evaluated. That is, you are
obliging Stata [sic] to evaluate whatever is on
the RHS of the equals sign. Now in this case
Stata is going to look at

"v1 v3 v5 v11"

and decide that it evaluates to, well,

"v1 v3 v5 v11"

-- so no change there. In short, there is no
work to do and you are no worse off asking Stata
just to _copy_, which it does when the equals sign
is not present,

local nv1 "v1 v3 v5 v11"

-- in fact, better off, as the limit that may bite
is no longer operating and the limit on the length of macro
that you can process in this way is not a concern.

Second, you can't wildcard local macro names, as in
your

local nv*

All that you can wildcard in Stata are varlists. Stata
will, I guess, just end up confused by your syntax here,
as even if you have defined a local

nv

the * still needs evaluation. Perhaps Stata thinks you
are making a comment, in which case it can't see the brace.

Third, those " " on the LHS are illegal too as
they can't be a part of a variable name and
they won't disappear on macro evaluation.

Fourth, you don't want the same macro on
either side of the equals sign, as contemplation of

egen rowsumv1 v3 v5 v11 = rowtotal(v1 v3 v5 v11)

will make clear.

Fifth, this should be closer to a solution.
Note: untested code.

forval i = 1/9 {
    egen rowsum`i' = rowtotal(`nv`i'')
    egen rowmean`i' = rowtotal(`nv`i'')
    egen dumvar`i' = anymatch(`nv`i''), values (1/5)
}

The trickiest part is on the RHS. The macro calls
are nested.

`nv`i''

but think back to the basic rules of algebra and
recall that you, and also Stata, work from the inside of an expression
outwards. So first time round the loop Stata sees

egen rowsum1 = rowtotal(`nv1')

and then immediately afterwards

egen rowsum1 = rowtotal(v1 v3 v5 v11)

Basic tutorials in this territory include

SJ-2-2  pr0005 Speaking Stata:  How to face lists with  fortitude
Q2/02   SJ 2(2):202--222

demonstrates the usefulness of for, foreach, forvalues, and
local macros for interactive (non programming) tasks

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


Walter Forrest

I wondered if anyone could help me find a more efficient way to run
some very repetitive commands. I'm trying to create multiple versions
of several new variables using the egen functions. Since each version
of the new variables is based on the same set of original variables,
but the sets differ for each cluster of versions, I've been using local
macros to simplify matters:

local nv1 = "v1 v3 v5 v11"
local nv2 = "v2 v4 v9 v10"
.........
local nv9 = "v79 v81 v82 v108"

I had thought that perhaps the egen commands could then loop over each
macro, with the names of the new variables containing some reference to
the macro (so that I can see easily which original variables were
included in its calculation). I've tried several versions of the
following:

foreach list of local nv* {
    egen "rowsum`list'" = rowtotal(`list')
    egen "rowmean`list'" = rowtotal(`list')
    egen "dumvar`list'" = anymatch(`list'), values (1/5)
}

Unfortunately, I've been unable to get this to work. The most common
error message that I've encountered is that STATA requries "}" ... even
though I've included it each time.

Any advice/ideas would be appreciated. Is it just my syntax that is
flawed or is my basic approach also at fault?

*
*   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–2014 StataCorp LP   |   Terms of use   |   Privacy   |   Contact us   |   What's new   |   Site index