Statalist The Stata Listserver


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

Re: st: -generate- and run time contingencies


From   "Michael Blasnik" <[email protected]>
To   <[email protected]>
Subject   Re: st: -generate- and run time contingencies
Date   Tue, 31 Jan 2006 09:13:25 -0500

I think you just don't quite have a full grasp of working in Stata's vectorized way of thinking. Stata can access the values of a variable at any time. If you want to loop over observations you can use explicit subscripting when working with a variable, but this almost always a slower way of doing things. Instead, you can count if a condition is satisfied for all observations and repeat the loop until it is. This latter approach isn't a "trick", but a programming method. Nick's example used assert and then checked the return code, but an equivalent approach is to use the count command and then check r(N). You still haven't been able to provide an example that Stata can't do.


A classic algorithm (See Numerical Recipes...) for
generating values from Normal(0,1) would look
something like this in Stata, if -while- could
access the run-time value of a variable:

tempvar v1 v2 done
gen `done' = 0
while not `done'  {
   gen `v1' = 2.0 * uniform() - 1.0
   gen `v2' = 2.0 * uniform() - 1.0
   gen r = `v1' * `v2'
   gen `done' = (r < 1.0 ) & (r > 0.0) /*
}
etc.  more stuff
Here's one approach to replicate the above loop

tempvar v1 v2 done
gen `v1'=.
gen `v2'=.
gen r=.
count if !((r < 1.0 ) & (r > 0.0) )
while r(N)>0  {
   replace `v1' = 2.0 * uniform() - 1.0
   replace `v2' = 2.0 * uniform() - 1.0
   replace r = `v1' * `v2'
   count if !((r < 1.0 ) & (r > 0.0) )
}

Another example occurs when one wants to do what
I think of a "rippling" through from 1 to N, using
the run-time value of a previous case.
For example, to consecutively groups of cases
based on some kind of shared value of a key,
a natural approach in other languages would
be something that would not fit with Stata:

* More Code that wouldn't work in Stata
sort SomeKey
generate GroupID = 1 if _n ==1
replace GroupID = GroupID[_n-1] ///
                   if (_n > 1)  & !(SomeKey == SomeKey[_n-1])

I know there are ways to accomplish this goal in
Stata, but I'm trying to adapting my existing bag
of algorithmic tricks :-}.
Again, this just requires you to think in Stata's vectorized way.

sort SomeKey
bysort SomeKey: gen GroupID=_n==1
replace GroupID=sum(GroupID)

I like the suggested approach in a later posting of doing the following:

gen x = uniform()
gen byte OK = x >= 0.8
capture assert OK == 1
while _rc {
replace x = cond(x < 0.8, uniform(), x)
replace OK = x >= 0.8
capture assert OK == 1
}

However, it does seem odd that one needs to use what looks like a trick to get make a value of a variable something that -while- can access at run time. I wouldn't have thought of this.
As I said, this is not a true, but a programming method that takes advantage of Stata's approach. Instead of the while _rc and capture assert commands, it would just be like the first example I give -- using a while r(N) and count if...

If your point is that Stata's ado programming is different than what you're used to with another language, in part due to Stata's vectorized apporoach to operation, then that's true.

Michael Blasnik
[email protected]

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