Announcement

Collapse
No announcement yet.
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • Levelsof loop within a loop

    Hi, I am having trouble using levelsof in a loop within a loop. Each row of the data has a "country" and "region" variable. For instance,
    ID region country wave highested participation
    1 Latin America Mexico 1981-1984 1 1
    2 North American & Western Europe United States 1981-1984 2 0
    I am trying to create a graph based on the logistic regression for every country, and combine the graphs by region. I hope to use a double-loop to accomplish this but now am stuck and cannot find what's wrong with the codes.

    region is coded numerically range from 1-7 for 7 world regions.
    country is coded as string.

    Code:
    levelsof region, local(region_l)  //  foreach y of local region_l {    
          levelsof country if region_l== `y', local(country_l)
          foreach v of local country_l {
                  logit participation i.highested if region==`y' & country=="`v'" 
              }
          }
    and it returns nothing. I ran single loops for "region" and "country" and both works, but when combined they don't.
    My next step would be to add marginsplot and combine all the graphs of the countries in the same region, producing 7 graphs covering all regions. See below.

    Code:
    levelsof region, local(region_l)  //  foreach y of local region_l {    
          levelsof country if region_l== `y', local(country_l)
          foreach v of local country_l {
                  logit participation i.highested if region==`y' & country=="`v'"
                margins highested
                 marginsplot, ///
                saving(`v', replace)
              }
       
       graph combine `v', title("`y'")
          }
    Any help would be appreciated!

  • #2
    Have a look at http://www.stata.com/support/faqs/da...ach/index.html which discusses the generic problem of looping over a set of distinct values.

    For your region variable, you know there are underlying numeric values 1 to 7, so you can work with those directly. You don't need levelsof for that. We can avoid using it for your country variable, but I will stick with it to show what needs to be done to fix your code.

    This has more chance of working.

    Code:
    forval r = 1/7 {        
        levelsof country if region == `r', local(countries)    
        foreach c of local countries {        
            logit participation i.highested if country == "`c'"        
           margins highested        
           marginsplot, saving("`c'", replace)        
        }      
        local R : label (region) `r'
        graph combine `countries', title("`R'") saving(region_`r')
    }
    So what needs attention?

    1. In your code you refer to region_l as a variable when you mean region.

    2. Testing for being in a certain region on the inner loop is redundant, but does no harm.

    3. You need to watch out for spaces in country names. That would bite when saving graphs.

    4. You need to put the graph names in a bag one by one; otherwise you will just graph combine precisely one country plot for each region, the last one drawn. The bag is just a local macro here.

    5. I changed some of your names to make your code more readable. When you ask people to look at your code, making it as easy to read as possible helps. That's not a reprimand, just a reminder.

    6. We need to save each regional graph too for flexibility.

    EDIT: I in turn benefitted substantially from Clyde's comments.
    Last edited by Nick Cox; 09 Oct 2014, 19:03.

    Comment


    • #3
      There are several problems in your code.:

      foreach y of local region_l {

      needs to start on a separate line. As presented, it is commented out and has no effect.

      levelsof country if region_l== `y', local(country_l) should be:
      levelsof country if region_l== "`y'", local(country_l) because region_l is going to be a string, not a number.

      logit participation i.highested if region==`y' & country=="`v'" should be
      logit participation i.highested if region=="`y'" & country=="`v'" again assuming region is a string variable.

      The command
      graph combine `v', title("`y'") will only combine one graph: that of the last country looped through in the region. It should be:
      graph combine `country_l', title("`y'")


      Added later: I just noticed that you say that region is an encoded numeric variable, not a string. So my second and third corrections are wrong.

      Comment on Nick's solution: no need to build up that C local macro inside the loop: its contents are already in `countries'.

      Also, titling a graph with a number from 1 to 7 may not be the best thing from a reader's perspective. Since the numbers 1 to 7 are from an encoded variable, I would use title(`"`:label (region) `r''"').


      Last edited by Clyde Schechter; 09 Oct 2014, 18:54. Reason: Correct an error

      Comment


      • #4
        Sorry for the delay. Thank you Nick and Clyde. I took Clyde's comment and made the adjustment based on Nick's code.
        Now it works wonderfully. Thank you again!

        Comment


        • #5
          Sorry for recalling this issue but I am having trouble using levelsof in a loop within a loop.

          Code:
          levelsof schoolid, local(schoolid)
          
          foreach schoolid of local schoolid {
          
          levelsof grade if schoolid==`schoolid', local(grade)
          
          foreach var of local grade {
          samplepps select_`school'_`var' if grade==`var' & schoolid==`schoolid', size(t) n(1)
          }
          }
          
          egen select=rsum(select_*)
          drop select_*
          There are no errors occurred when running those codes, but it returns nothing.

          When listing some values of "schoolid" in the first loop, it runs properly. However, there are more than 600 values of this variable with 8 characters included in each value (eg 10105034) and I do not want to use this method.

          Please help me to solve this problem. Any suggestions would be appreciated.
          Thanks.
          Chau

          Comment


          • #6
            Chau: There is nothing here that we can check easily. samplepps is from SSC and written by @Stephen Jenkins.

            rsum() is an undocumented egen function as from Stata 9.

            This is a cleaner approach if I understand the problem correctly.

            Code:
            egen group = group(schoolid grade)
            su group, meanonly
            
            gen select = 0
            
            quietly forval j = 1/`r(max)' {
                 samplepps work if group == `j', size(t) n(1)
                 replace select = select + work
                 drop work
            }


            See also http://www.stata.com/support/faqs/da...ach/index.html

            Comment


            • #7
              Thanks Nick. That is exactly what I want. It works properly now.
              Once again, thank you so much !

              Chau

              Comment

              Working...
              X