How to loop through specific string values of a variable in Stata?

7.3k Views Asked by At

I want to loop through a specific subset vector of a string variable in Stata. I have a data set like:

id  country  effect  period
1   US       0.20    2
2   US       0.25    3
3   Japan    0.37    2
4   Germany  0.22    3
5   US       0.11    3
6   Japan    0.43    1
7   Ireland  0.30    1
...

I don't want to loop through all values of the country-variable, but only through specific values, e.g. US and Japan. I tried:

levelsof country if country=="US" | country=="Japan", local(countrylev)
levelsof period, local(periodlev) //periods are 1,2,3,4
mat m = J(2,4,.)
local i=1
local j=1

foreach x of local countrylev {
 foreach per of local periodlev {
    mat m[`i',`j']=`per' *2
    local ++j
    mat m[`i',`j']=`per' *3
    local ++j 
    mat m[`i',`j']=`per' *3
    local ++j 
    mat m[`i',`j']=`per' *4
    local ++i
    local j=1
 }
 matrix list m
}

However this only loops through "Japan"...

1

There are 1 best solutions below

2
On

I have to guess that the answer lies in the data or the code you have represented by dots. For example, check for trailing spaces such as "US ".

For cycling over two distinct values, you can be direct and say

foreach c in US Japan { 
   <stuff> if country == "`c'" 
}

except that (as above) trailing spaces could undermine that. Use trim() if spaces are the problem.

It is often easier to map to a numeric variable and then use the distinct numeric values you want. That is especially true when you have blanks and/or other punctuation to handle too. For more, see (e.g.) this FAQ (which is more relevant than the title implies; see Method 1).

UPDATE

Revised code makes matters more puzzling, not less. Your code seems to boil down to

mat m = J(2,4,.)

forval i = 1/2 {
    forval j = 1/4 {
        mat m[`i',`j']=`j'*2
        mat m[`i',`j']=`j'*3
        mat m[`i',`j']=`j'*3
        mat m[`i',`j']=`j'*4
    }
}

matrix li M 

as listing the matrix each time around the loop doesn't seem important.

Indeed, the example seems to collapse to one line

mat M = (2,3,3,4)' * (1,2,3,4) 

However, you may have simplified something important for you out of the problem to focus on what is problematic in terms of code.