# st: How to program a loop to calculate the value of an observation

 From Andreas Reinstaller To statalist@hsphsun2.harvard.edu Subject st: How to program a loop to calculate the value of an observation Date Sat, 03 Feb 2007 12:25:02 +0100

Dear Stata-community

I have a multicountry panel of industrial sector data where I have observations for instance for the number of firms, the turnoveror people employed grouped in specific size classes, defined say as firms smaller than 10 employees, between 10 and 50, and so forth. With these data I try to calculate a concentration index. While the data are sectoral the index to be calculated makes some assumptions about the size distribution of firms within each size class to calculate the concentration (for the initiated it is a Schmalensee concentration index, as used for instance in the OECD Structural and Demographic Business Statistics). More specifically, the index uses the number of firms in each size class, as well as information on turnover, employment etc in that class, to proxy the size of each firm in that size class. Line local sz=((100* .... in the little code fragment below shows how it is done.

Now my first -- clearly unsuccessful trial -- to get my index looked as follows. I just report it in order for you to grasp what I want to do, as it is a program that did not work:

Calling it with:

by country year sectorcode sizeclass: ave_hhi NoFirms SizeclassEmploym SizeclassTurnover SectoralTurnover EmplThreshold_sizeclass

it should do

program define ave_hhi, byable(recall)
syntax varlist(min=5 max=5 numeric) /*, newvarname(string) */
marksample touse
tokenize `varlist'
local ni `"`1'"'
local Ei `"`2'"'
local Si `"`3'"'
local S `"`4'"'
local EMi `"`5'"'

if `touse'{
local szs = 0
if (`ni'!=0){
if (`ni'==1) {
local szs=(`ni'*(100*(`Si'/`ni')/`S' )^2) }
else {
local j = 0
while `j' <= `ni' {
local sz = 0
local sz = ((100*((`Si'/`Ei'*`EMi')+(2*`j'*(`Si' -(`ni'*(`Si'/`Ei'*`EMi')))/(`ni'*(`ni'-1))))/`S')^2)
local szs = `szs' + `sz'
local ++j
}
}
/* quietly gen `newvarname'=`szs'*/
replace newntx=`szs'
}
else {
/* quietly gen `newvarname'=0*/
replace newntx=.
}
}
end

Now, this of course, as the Stata FAQs on using the if qualifier vs if command in programs argues (http://www.stata.com/support/faqs/lang/ifqualifier.html) will not work. The if's and the while are used - in line with Stata syntax - badly. The program will (and indeed does) just check the if (`ni'!=0) for one time, keeps the result and - as the first data in my set this condition is not fulfilled - replaces all newntx with a dot. The same problem would come up later when the program would run through the "while" loop condition. The FAQ section suggests I use if as a qualifier in a generate or replace command rather than as a command in itself, but as my calculation involves evaluating the while loop to get the value I want to replace, this is definitely not an option. I can do it for the if (`ni'==1) condition, as it does not involve the loop and I could directly assign the value, but that does not really help.

Being used to program in Matlab or any other programming language, my next idea was to specify a function, that would return exactly the value that is calculated in the loop so that I could use the return value in the replace/generate command using the if qualifier for all conditions `ni'>1, like for example the functions that can be used jointly with the egen command. However, browsing trough the Statalist archive, I see that Stata does not allow to specify any such function.

Finally, I thought to circumnavigate the problem by just simply specifying a little program where I transform the variables I need into matrices and do the calculations by using the Stata matrix commands - a little bit as if I was using Matlab. However, as my variables have more than 60000 observations I run into a matsize problem and can't pursue this avenue as well.

Now: does anybody see a way how I could get what I want easily, so that I don't have to export my data into Matlab and do this simple calculation there?

Any help is very much appreciated!

Best,
Andreas

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