Announcement

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

  • Problem with macros in a foreach loop

    Hello,

    I have a problem when I try to call a global macro within a foreach loop.

    I need the number of missing values for each observations over a series of "relevant" variables. The "relevance" of these variables comes from another variable (in the example dataset, the variable "group"). For example, looking at the code I am providing below, var1, var2 and var3 are relevant for the observations falling in the group 1000.
    I decided to proceed as follows:

    ------------------
    Code:
    global groups_all 1000 1001 2030 4030 // one global macro containing all the possible groups
    global group_code_1000 var1 var2 var3 // a number of global macros containing the relevant variables for each group
    global group_code_1001 var1 var3 var7
    global group_code_2030 var5 var6 var8 var14
    global group_code_4030 var10 var9 var11 var12 var14 var15
    
    gen relevant_missings = . // the variable I need to fill
    
    foreach group in $groups_all {
        egen miss_`group'=rowmiss($group_code_`group') // here is where the error comes from: "1000 invalid name" r(198); plus, through set trace on, it seems Stata does not recognizes I am calling a global macro within rowmiss (it seems running rowmiss(1000)
        replace relevant_missings=miss_`group' if group==`group'
        drop miss_`group'
    }
    ------------------

    Here is an example of my dataset. I have changed names due to privacy reasons.

    ------------------
    Code:
    clear
    input int(year line) str4 var1 byte var2 str4(var3 var4) double var5 str4(var6 var7) byte var8 double var9 str4(var10 var11) byte var12 str4 var13 double(var14 var15) long group
    2017  59 "Y   "  91 "Y   " "Y   "               100 "Y   " "Y   " 100 0 "Y   " "Y   " 0 "Y   " 10                 80 1000
    2018  59 "Y   "  89 "Y   " "Y   "               100 "Y   " "Y   " 100 0 "Y   " "Y   " 0 "Y   " 10                 30 1000
    2019  59 "Y   "  95 "Y   " "Y   "               100 "Y   " "Y   " 100 0 "Y   " "Y   " 0 "Y   " 10                 30 1000
    2020  59 "Y   "  93 "Y   " "Y   "               100 "Y   " "Y   " 100 0 "N   " "Y   " 0 "Y   " 10  33.33000183105469 1001
    2017 566 "N   "  87 "Y   " "N   " 66.66999816894531 "Y   " "Y   " 100 . "Y   " "Y   " 1 "Y   "  0  28.56999969482422 1001
    2018 566 "N   "   . "Y   " "N   " 66.66999816894531 "Y   " "Y   " 100 . "N   " "Y   " 1 "Y   "  0               37.5 2030
    2019 566 "N   "  82 "Y   " "N   " 66.66999816894531 "Y   " "Y   " 100 0 "Y   " "Y   " 1 "Y   "  0  28.56999969482422 2030
    2017 283 "N   " 100 "N   " "N   "               100 "Y   " "Y   " 100 . "N   " "N   " 2 "Y   "  0 23.079999923706055 4030
    2018 283 "N   "  94 "N   " "N   "               100 "Y   " "Y   " 100 . "Y   " "Y   " 0 "N   "  0                 30 4030
    2019 283 "N   "  91 "N   " "N   "               100 "Y   " "Y   " 100 . "N   " "Y   " 0 "Y   "  0 27.270000457763672 4030
    end
    ------------------

    Please, let me know if there is a way to call a macro within a foreach loop (it may be useful for other purposes, too), and if there is a better way to do that task.
    Lastly, apologies if I have not posted this question correctly (in case, please, let me know). This is my first post, and I hope everything is ok.

    Thank you in advance.


  • #2
    The easiest solution is to just don't use globals, they are evil anyhow.
    Code:
    local groups_all 1000 1001 2030 4030 // one global macro containing all the possible groups
    local group_code_1000 var1 var2 var3 // a number of global macros containing the relevant variables for each group
    local group_code_1001 var1 var3 var7
    local group_code_2030 var5 var6 var8 var14
    local group_code_4030 var10 var9 var11 var12 var14 var15  
    
    foreach group in $groups_all {
        egen miss_`group'=rowmiss(`group_code_`group'')
         drop miss_`group'
    }
    Last edited by Maarten Buis; 25 Nov 2022, 07:40.
    ---------------------------------
    Maarten L. Buis
    University of Konstanz
    Department of history and sociology
    box 40
    78457 Konstanz
    Germany
    http://www.maartenbuis.nl
    ---------------------------------

    Comment


    • #3
      Another solution (though I agree with #2 that globals are evil!)

      change the offending line to:

      Code:
      egen miss_`group'=rowmiss(${group_code_`group'})

      Comment


      • #4
        Thank you very much! Both solutions seem to work.
        Thank you also for suggesting to use local macros instead of globals. Probably, this is just a glimpse of how evil they can be.

        Have a nice day

        Comment

        Working...
        X