1

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"...

3
  • 1
    Describing the ultimate purpose of this might get you better advice. Commented Jun 15, 2015 at 13:19
  • 1
    This question has yet to yield an intelligible, clear and reproducible problem. I've commented on your revised code in an updated answer. As the code reduces to something trivial, I think you edited your real problem out. Commented Jun 16, 2015 at 11:01
  • You are totally right. Sorry for that. I'll delete my question as it is not value adding for other users. Commented Jun 17, 2015 at 1:50

1 Answer 1

3

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.

Sign up to request clarification or add additional context in comments.

2 Comments

Thanks! You are totally right. The problem is the content in the dots. I edited my question. The issue is that I receive a confirmability error r(503). I think there is a problem with the matrix 'm' after the first loop... Could you help me with this?
At a minimum, your foreach per of local period should be for periodlev, not period.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.