Announcement

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

  • Define Variables in a loop

    Dear all,

    I would like to run a regression for three different (dependent) variables in a loop, which looks as follows:

    Code:
    foreach v of varlist var1 var2 var3 {
    reghdfe `v' i.post##i.Treatment##i.young `ind_controls', cluster(district) absorb(district)
    outreg2 using "test.doc", append ctitle(`v')
    Importantly, I want another variable in the regression to take different values, depending on the respective varlist variable.
    More precisely, I have two age groups, say, "young1" and "young2". I want to use age group "young1" for the first two variables of my loop (var1 and var2) and age group "young2" for the third variable (var3).

    I was wondering if it is possible to run all this in a single loop?
    For me it is important that the variable name ("i.young") is the same for both age groups, such that the results are stored in the same row in the doc that is created with outreg.

    I first tried something like this (where young1 and young2 are my pre-defined age cohorts):

    Code:
    foreach v of varlist var1 var2 var3 {
    
    gen young=.
    replace young=young1 if `v'==var1 | `v'==var2
    replace young=young2 if `v'==var3
    
    reghdfe `v' i.post##i.Treatment##i.young `ind_controls', cluster(district) absorb(district)
    outreg2 using "test.doc", append ctitle(`v')
    drop young
    Any help would be appreciated. Thanks in advance,
    Guest
    Last edited by sladmin; 10 Jun 2021, 06:35. Reason: anonymize original poster

  • #2
    Could you use an if statement within the loop?

    Something like:
    Code:
     
     foreach v of varlist var1 var2 var3 { if(`v'==var1 | `v'==var2){ reghdfe `v' i.post##i.Treatment##i.young1 `ind_controls', cluster(district) absorb(district) } else{ reghdfe `v' i.post##i.Treatment##i.young2 `ind_controls', cluster(district) absorb(district) } outreg2 using "test.doc", append ctitle(`v') }
    Let me know if that works

    Best,
    Rhys

    Comment


    • #3
      In your if clauses on the replace commands, you need to surround `v' and var1, var2, and var3 with double quotes, thus
      Code:
      replace young=young2 if "`v'"=="var3"
      Lacking the double quotes, you are running commands like
      Code:
      replace young=young2 if var2==var3
      which is comparing the values of the variables, not their names.

      Comment


      • #4
        Dear Rhys, Dear William,

        Thanks for your answers.

        Your code works perfectly fine, Rhys, thanks for this.

        Finally, adding the quotes as William mentioned, I guess that the shortest command for my purpose would however be:

        Code:
        foreach v of varlist var1 var2 var3 {
        
        gen young=.
        replace young=young1 if "`v'"=="var1" | "`v'"=="var2"
        replace young=young2 if "`v'"=="var3"
        
        reghdfe `v' i.post##i.Treatment##i.young `ind_controls', cluster(district) absorb(district)
        outreg2 using "test.doc", append ctitle(`v')
        drop young
        }
        This allows me to type the regression command only once.

        Best,
        Guest
        Last edited by sladmin; 10 Jun 2021, 06:35. Reason: anonymize original poster

        Comment


        • #5

          This is shorter. You don't need a new variable -- you just use one or other existing variable as you wish.

          Note that the test of whether this is the third time round need only be done once -- with an if statement -- not again and again for each (meaning, every!) observation with an if qualifier.


          Code:
          local young young1 
          
          forval j = 1/3 {
          
          if `j' == 3 local young "young2" 
          
          reghdfe var`j' i.post##i.Treatment##i.`young' `ind_controls', cluster(district) absorb(district)
          
          outreg2 using "test.doc", append ctitle(var`j') 
          
          }

          Comment


          • #6
            The code from post #2, rendered a little more readably:
            Code:
            foreach v of varlist var1 var2 var3 {
                if (`v'==var1 | `v'==var2) {
                    reghdfe `v' i.post##i.Treatment##i.young1 `ind_controls', cluster(district) absorb(district)
                }
                else {
                    reghdfe `v' i.post##i.Treatment##i.young2 `ind_controls', cluster(district) absorb(district)
                }
                outreg2 using "test.doc", append ctitle(`v')
            }
            Lacking double quotes around `v', var1, and var2 the if statement is interpreted as, for example
            Code:
                if (var3==var1 | var3==var2) {
            again comparing values of the variables rather than names of the variables. But with the if statement, which as Nick points out in post #5 is evaluated only once, the value of a variable is its value in the first observation, so the if statement is effectively
            Code:
                if (var3[1]==var1[1] | var3[1]==var2[1]) {
            Should, in the first observation, the value of var3 and either var2 or var1 be the same, the variable young1 would be used is the regression for var3, which is not what is wanted.

            As before, the if statement should have double quotes, thus
            Code:
                if ("`v'"=="var1" | "`v'"=="var2") {
            Or better yet, adopt Nick's approach from post #5.

            Comment


            • #7
              Great, good to know Nick.

              Thank you all.

              Best,
              Guest
              Last edited by sladmin; 10 Jun 2021, 06:36. Reason: anonymize original poster

              Comment

              Working...
              X