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

st: RE: scalars in loops


From   "Nick Cox" <n.j.cox@durham.ac.uk>
To   <statalist@hsphsun2.harvard.edu>
Subject   st: RE: scalars in loops
Date   Wed, 16 Jun 2004 00:28:03 +0100

Here's one take. I attempt to make 
up for lack of rigour here by 
expenditure of vigour, which never
gets high grades. 

You are trying to treat a scalar 
as if it were a local. It is not the 
same thing; if it were, one of the ideas
would be redundant. Rather, a scalar _name_ 
can be a local macro. (It could be something
permanent, as well.)  

A local has no real use unless its name 
is written down, so that Stata sees the 
name and substitutes the contents. 
(You _could_ always just put 
something into a macro and do nothing 
with it, but that would be pointless.) 

As a consequence, writing down 
a local as part of a command in effect 
gives you its contents straight away: 

local i = 1 
gen mpg`i' = mpg + `i' 

immediately yields 

gen mpg1 = mpg + 1 

It's as if defining a local macro were 
like putting something in a transparent 
box. That is, someone's given you 
a present in a box, but the box is 
transparent, so that immediately 
you can see what the present is. It's 
Stata 10! (Just kidding.) 

You know all this. So how does a scalar 
differ? With a scalar the box is 
less transparent. Depending on context, 
you may get first the _name_, not the contents, 
which is not what you want. 

tempname foo 
scalar `foo' = 3 
forval i = 1/`foo' { 
	... 
} 

will fail because here Stata sees the 
name `foo' -- really __000002 or 
some such -- when what it wants in this 
context is a number -- and what you want, similarly, 
is that Stata sees a number. 

This would work: 

forval i = 1/`=`foo'' { 
	...
} 

in which you force Stata to evaluate
your expression (here just a single name, 
but the principle is the same), 
i.e. to look beyond the name and 
find the contents, to open the box, 
in short. 

Note that appealing to -display- 
muddies the distinction here, and 
makes the difference between locals 
and scalars with local macro names seem 
smaller than it really is. It is -display-'s job 
to open boxes -- that is precisely 
what is designed to do. It is 
a pair of scissors and a knife 
and a little helper all in one. 

However, -forval- 
does not have the job of opening 
boxes. It does none of that. Before 
-forval- does anything, however, 
the parser does substitute macro 
references. With a local macro 
that's enough. With a scalar 
you need to go one step further, 
because the name is not what you need. 

Context is important here. With 
the same scalar on the right-hand 
side

gen bar = `foo' + 5

Stata again is evaluating and 
so looks inside the box. This 
is just what you expect from 
first lessons in Stata: with 

gen mpg2 = mpg + 5

Stata is obliged by the context
to look beyond the (variable) 
name -mpg- and get at the contents, 
the values of the variables. 

-set trace on- helps you see 
what's happening here. 

Moral: Keep straight the difference
between names and contents, between 
what is on the outside of the box
and what's inside. 

P.S. -while-? Well, I have no 
special story here. Evidently, 
Stata was written so that the 
-while- context forces evaluation. 
Perhaps the designers of Stata 
can spell out the logic. 

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

Dimitriy V. Masterov
 
> Can someone please explain to me why one cannot use scalars 
> to define the
> upper bound in a range of a forvalues loop. A forvalues loop 
> with a local
> works,  a while loop with a scalar works, a while loop with a 
> local works,
> but not a forvalues loop with a scalar. There seems to be 
> nothing in the
> programming manual about this issue.
> 
> This is the code for the examples above:
> 
> tempname m1 m2
> 
> scalar `m1'=5
> local `m2'=5
> 
> 
> forvalues a=1(1)``m2'' {
> 	di "`a'"
> }
> 
> local a=1
> 	while `a'<=``m2'' {
> 		di "`a'"
> 	local a=`a'+1
> }
> 
> 
> local a=1
> 	while `a'<=`m1' {
> 		di "`a'"
> 	local a=`a'+1
> }
> 
> forvalues a=1(1)`m1' {
> 	di "`a'"
> }
> 
> I am using Stata 8.2 SE with XP.
> 

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