Announcement

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

  • Use local in global

    Dear statalists,

    I am not entirely sure whether "use local in global" is an appropriate description for my problem but here is what I would like to do:

    I am running several regressions for different dependent variables. The dependent variables differ in the year they refer to.

    Code:
            foreach year of numlist 1950(10)1990 {
    
                global control_dist1_`year'     weighted_dist_y`year'
                global control_dist2_`year'     weighted_dist_y`year' c.weighted_dist_y`year'#c.weighted_dist_y`year'
                global control_dist3_`year'     weighted_dist_y`year' c.weighted_dist_y`year'#c.weighted_dist_y`year' c.weighted_dist_y`year'#c.weighted_dist_y`year'#c.weighted_dist_y`year'
    
            }
    
            foreach year of numlist 1950(10)1990 {
    
                reg mig_total_`year' weighted_sc_initial10_y`year' $control_dist1_`year' $control_pop_`year', robust            // linear dist control
                reg mig_total_`year' weighted_sc_initial10_y`year' $control_dist2_`year' $control_pop_`year', robust            // quadratic d control
                reg mig_total_`year' weighted_sc_initial10_y`year' $control_dist3_`year' $control_pop_`year', robust            // cubic dist. control
                
            }
    First, I would like to define for globals for different control variables. With a foreach loop, I define these for every decadal year between 1950 and 1990. Then, when running the actual regressions, I would like to use these controls but only for the year in the dependent variable.

    The result is that I try to call upon a local (from foreach loop) within a global (previously defined). For example,
    Code:
    $control_dist1_`year'
    This does not work. Stata gives the error:
    1950 [i.e. the first year in the foreach loop] invalid name
    .

    Did I miss something obvious? Is this possible at all?

    Many thanks,
    Milan

  • #2
    Try
    Code:
    ${control_dist1_`year'}
    The squiggly brackets tell Stata to evaluate what's inside and use the results as the name for the global. Right now, Stata thinks you are asking for the variable that is made by the combination of $control_dist1_ and `year'. Since you never defined $control_dist1_, you just get 1950 as your variable name.

    On the other hand, is there a reason you need to use globals here? Why not locals?

    Comment


    • #3
      Thank you, that's the solution.

      At the moment, I prefer globals over locals because I am still analyzing the data which makes it more convenient if I can run parts of the do-file (so I do not get spammed with output I do not need).

      Thank you again for your help.

      Comment


      • #4
        At the moment, I prefer globals over locals because I am still analyzing the data which makes it more convenient if I can run parts of the do-file (so I do not get spammed with output I do not need).
        There is a better solution to this problem. Actually there are two better solutions to this problem.

        Solution 1. Comment out the unwanted sections of code that fall between the definitions of the local macros and the code you want to run. If you are running the up-to-date version of Stata this is now easier than ever before. Just highlight (select) the code you want to skip in the do-editor and then press control and / together (this is Windows, I'm not sure what the corresponding maneuver is in Mac.) The code will be commented out. When you want to un-comment it later on, just re-highlight it and press control and / together again, and the commenting will go away.

        Solution 2. Put the local macro definitions in a separate do-file. For illustration here, I'll call that file local_macro_definitions.do. Then, immediately before the code where you want to use them put:

        Code:
        include local_macro_definitions
        Note that the command here is -include-, not -do- or -run-. The -include- command causes Stata to virtually insert the contents of the mentioned file into the active do file, just as if it were actually part of that file. So your locals get defined there and are in scope. The -include- command is also very useful when there are local macro definitions or other code segments that you want to always use identically in multiple do-files.

        Global macros are dangerous and should only be used when there is no viable alternative.

        Comment


        • #5
          Roger's "squiggly bracket" looked a new term but see

          http://www.catb.org/jargon/html/A/ASCII.html

          for a canonical list which includes it. If people don't understand parenthesis/bracket/brace I tend to explain them as round, square and curly brackets. We're talking ( ) [ ] { }.

          Roger answered the main question, to which I add that the two loops can just be collapsed to one so far as I can see. This version shows an aversion to globals and a preference for forval when allowed. I've left the global defined previously in place.

          Code:
          forval year = 1950(10)1990 {
              local control_dist1  weighted_dist_y`year'
              local control_dist2  weighted_dist_y`year' c.weighted_dist_y`year'#c.weighted_dist_y`year'
              local control_dist3  weighted_dist_y`year' c.weighted_dist_y`year'#c.weighted_dist_y`year' c..weighted_dist_y`year'#c.weighted_dist_y`year'#c.weighted_dist_y`year'
          
              reg mig_total_`year' weighted_sc_initial10_y`year' `control_dist1' $control_pop_`year', robust            // linear dist control
              reg mig_total_`year' weighted_sc_initial10_y`year' `control_dist2' $control_pop_`year', robust            // quadratic d control
              reg mig_total_`year' weighted_sc_initial10_y`year' `control_dist3' $control_pop_`year', robust            // cubic dist. control      
          }
          A completely different point is that I wouldn't trust plain linear regression for migration totals and distances (I guess at variable identities) and so forth! Poisson regression seems a more natural default.

          Comment


          • #6
            Clyde Schechter
            Thanks a lot for the comment. Solution 1 would be awesome indeed but somehow it does not work for me (even though I use windows). When I press control and / nothing happens. When I then run the do-file, no part is excluded.

            As for the second solution that seems a very good idea. Probably much more convenient than globals. Thank you!

            Nick Cox
            Thank you for your suggestions. I did not include both loops in one because they are followed by more regressions (which I omitted here for brevity) and I wanted to define the locals/globals in a separate part of the do-file. The preference for forval is a fair point. I might try it some time. (This being said, is there any case where foreach x of numlist does not work but forval does? Are foreach of numlist and forval 'equivalent'?

            Thank you also very much for the hint at Poisson. This is very valuable for me. Thanks!

            Comment


            • #7
              You can have other code in the single loop too.

              In general, defining locals (or globals) substantially in advance of when they are needed -- if that is what you are doing -- often proves a source of confusion or even bugs. Just in time is best advice.

              foreach and forval are not equivalent at all as forval is much more specific in what it can do. This can be seen from the help. The preference for forval when it is allowed is in faster, cleaner code.

              Comment

              Working...
              X