Title | Stata 7: Nested for commands | |
Author | Kenneth Higbee, StataCorp |
The for command's syntax uses the backslash ("\") in two different ways. One way is as a separator for multiple lists in the first part of the syntax (the part before the colon). The other way, the backslash is used as a separator for multiple commands to be executed during the loop (the part of the syntax after the colon).
That the backslash has two different meanings depending on its position leads to an ambiguity in interpretation with certain nested for commands. This is why some nested for commands produce an error.
Here is what for does:
At this step, if there is another (nested) for command in part2 that also uses the backslash as part of its syntax, then all of these backslashes are interpreted as separators of commands for the first for loop. This is what causes the error.
Here is a nested for command example that causes no ambiguity because there are no backslashes used.
. for A in num 1/2, noh : for B in num 1/3, noh : display "A,B" 1,1 1,2 1,3 2,1 2,2 2,3
The noh above is shorthand for the noheader option that suppresses all the extra information for usually presents before executing the command(s) at each loop iteration.
Also
. for A in num 1/2 \ B in num 5/6, noh: for X in num 1/3, noh: disp "A,B,X" 1,5,1 1,5,2 1,5,3 2,6,1 2,6,2 2,6,3
has no ambiguity because all of the backslashes (only one in this case) occur before the first colon.
However,
. for A in num 1/2 : for X in num 1/3 \ Y in num 7/9 : di "A,X,Y" -> for X in num 1/3 invalid syntax r(198);
does not work. Here is why:
A in num 1/2
for X in num 1/3 \ Y in num 7/9 : di "A,X,Y"
part2 is examined for backslashes that signal the division between multiple commands. It finds one backslash and sets up two commands:
- cmd1 is
for X in num 1/3
- cmd2 is
Y in num 7/9 : di "A,X,Y"
neither of which are valid commands. for now tries to execute the loop by setting the "A"'s to 1. cmd1 and cmd2 then become
- cmd1 is
for X in num 1/3
- cmd2 is
Y in num 7/9 : di "1,X,Y"
and then cmd1 is executed, producing the error message we see.
You might be tempted to ask why Stata isn't smart enough to see that the backslash does not belong with the first for loop? For simple examples like the one above, it is possible to think of algorithms to determine the context of the backslash (for example, searching for the word "for" in part2 to determine if there is nesting or searching for multiple colons). However, in a general setting, these methods will not work given the current syntax of for. For instance, "for" can appear as a name in some other context (for example, as a variable name or abbreviation of a variable name), and colons are also used by other commands (like by).
When you need the functionality of nested for commands, you can always turn to nested while loops instead.
for A in num 1/2 : for X in num 1/3 \ Y in num 7/9 : di "A,X,Y"
This is incorrect, but it can be rewritten as
local A 1 while `A' <= 2 { local X 1 local Y 7 while `X' <= 3 { di "`A',`X',`Y'" local X = `X' + 1 local Y = `Y' + 1 } local A = `A' + 1 }
which produces
1,1,7 1,2,8 1,3,9 2,1,7 2,2,8 2,3,9
The motto is nested for commands that use backslashes after the first colon will not work due to the dual purposes served by the backslash in the for command syntax. Instead, use the foreach or forvalues commands for these cases.