Announcement

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

  • looping over a subset of the full dataset

    Here is a piece of code that loops thru every year and runs a regression for each individual year.

    Code:
    webuse grunfeld, clear
    set seed 06182021
    forval i=1/5{
        gen var`i'= runiformint(1,`i'0)
    }
    
    local i 0
    levelsof year, local(years)
    foreach year of local years{
        regress invest var1 var2 var3 var4 var5 if year==`year', vce(cluster company)
        local opt= cond(`i'==0, "replace", "append")   
        outreg2 using myfile, `opt' ctitle( "`year'") excel
        local ++i
    }
    I would like to use a similar loop to run regressions over 2 different time windows (not year by year) where one time window is a subset of the total (1935-1950) and the other is the total (1935-1954). The two different periods are: i) all years less than 1951 -and- ii) all years less than 1955 (the last year in the data is 1954).

    My code doesn't work because I don't know how to call the loop. (I am not great at loops.)

    I would also like to label the end/last/final year used in the regression using outreg2 (which I know many giving help on here are not users of). I'm not sure how to do that. I feel year_x belongs in the label, but not sure?

    Code:
    webuse grunfeld, clear
    set seed 06182021
    forval i=1/5{
        gen var`i'= runiformint(1,`i'0)
    }
    local i 0
    local yearlist "1951 1955"
    forvalues year<year_x of local yearlist{
        regress invest var1 var2 var3 var4 var5 , vce(cluster company)
        local opt= cond(`i'==0, "replace", "append")   
        outreg2 using myfile, `opt' ctitle( "`year_x'") excel
        local ++i
    }
    Thanks in advance.

  • #2
    Seems like you want something like this:

    Code:
    webuse grunfeld, clear
    set seed 06182021
    forval i=1/5{
        gen var`i'= runiformint(1,`i'0)
    }
    local i 0
    foreach year in 1950 1954{
        regress invest var1 var2 var3 var4 var5 if year <= `year', vce(cluster company)
        local opt= cond(`i'==0, "replace", "append")
        outreg2 using myfile, `opt' ctitle( "`year'") excel
        local ++i
    }

    Comment


    • #3
      Setting aside details secondary to the main question, this is a little tricky and Stataish but it does what is intended.

      Code:
      webuse grunfeld, clear
      
      foreach period in 1935,1950 1935,1954 {
          di 
          summarize year if inrange(year, `period')
          di 
          regress invest mvalue if inrange(year,`period') 
      }
      The
      Code:
      summarize
      is just to show that the device works.

      That said, anyone indifferent or hostile to Stata is likely to react negatively to such trickery and I don't particularly recommend it either to Stata enthusiasts. It is more by way of an in-joke about how Stata may work.

      Comment


      • #4
        Daniel/Nick,

        Thank you very much.

        I am doing many nested loops. Most I can figure out, this one gives me trouble.

        Comment


        • #5
          Everything seems to be working well....but I cannot fit ranges (2 values in 1 cell) in the outreg2 output file. Any idea how to do that?

          Daniel, I appreciate you showing me how to put the end year (1 value) in the label, but what if the ranges were (see code below): i) 1940-1950 -and- ii) 1935-1954? Then the end year would not be sufficient.

          I need to put 2 values in each label cell. I tried many things, but couldn't get it.

          I tried (in place of "`year'" in the below code):
          "`year'","`year'"
          "`year',`year'"
          "`year'" "`year'"

          Not sure what else to try?

          Code:
          webuse grunfeld, clear
          
          local i 0
          foreach period in 1940,1950 1935,1954 {
              regress invest mvalue if inrange(year,`period')
              local opt= cond(`i'==0, "replace", "append")
              outreg2 using myfile.xls, `opt' addtext(Year, "`year'") excel
              local ++i
          }
          Thanks in advance. Grateful for this community.

          Comment


          • #6
            I don't know outreg2 (from SSC???) to comment on what it needs, but in #5 there is a reference to a local macro year that doesn't seem to be defined in your code.

            In any case. what happens with your code? What do you want to happen?
            Last edited by Nick Cox; 30 Oct 2024, 19:48.

            Comment


            • #7
              Nick Cox : thanks for the reply.

              I am not smart/experienced/great at macros. Apologies in advance.

              Yes outreg2 is from SSC. Sry I didn't point that out. I know you are not a user of it (from previous/other posts).

              What I would like to have the code do is to label the year range in the outreg addtext (single) cell. For the above code, I would like the first specification/regression cell to contain 1940,1950 and the second to include 1935,1954. It has to be in the same cell.

              This (below) code, for example, labels the year (1940 or 1954), but my problem is when there is a range of values and I need to fit the range (2 values) into one cell (like in the previous post; where the ranges were 1940,1950 and 1935,1954).

              Code:
              webuse grunfeld, clear
              
              local i 0
              foreach period in 1940,1940 1954,1954 {
                  regress invest mvalue if inrange(year,`period')
                  local opt= cond(`i'==0, "replace", "append")
                  outreg2 using myfile.xls, `opt' addtext(Year, "`period'") excel
                  local ++i
              }
              Thanks again for the help.

              Comment


              • #8
                Thanks; that code fixes the problem of the undefined macro.

                As you realise, you need someone with experience in outreg2 to advise further.

                Comment


                • #9
                  Regarding, calling the regression range....

                  Would you know how to split the range into 2 variables: give the start year a variable and the end year a different variable? Instead of saying foreach period in...., if we could say foreach period1,period2 in... I think my issue would be resolved.

                  Something like (but I know this doesn't work).....

                  Code:
                  webuse grunfeld, clear
                  
                  local i 0
                  foreach period1,period2 in 1940,1940 1954,1954 {
                      regress invest mvalue if inrange(year,`period')
                      local opt= cond(`i'==0, "replace", "append")
                      outreg2 using myfile.xls, `opt' addtext(StartYear, "`period1'",EndYear, "`period2'") excel
                      local ++i
                  }

                  Comment


                  • #10
                    There is, as you say, no such syntax.

                    if the window is fixed width, you can loop over starts and calculate ends inside the loop. Or vice versa.

                    Otherwise all syntaxes I can think are variations on #3 but usually less quirky.

                    Comment


                    • #11
                      You can also use two lists to get something equivalent to an iterable list of tuples. Just remember the length of both lists must be the same and the matching start and end years must have the same index.

                      Code:
                      local period_start = "1940 1941 1942 1943"
                      local period_end = "2000 2001 2002 2003"
                      
                      local start_count = wordcount("`period_start'")
                      local end_count = wordcount("`period_end'")
                      
                      assert `start_count' == `end_count'
                      
                      forvalues i = 1/`start_count' {
                          local start_year = word("`period_start'", `i')
                          local end_year = word("`period_end'", `i')
                          display "Start:`start_year', End:`end_year'"
                      }


                      This is just the general form, I have no idea what your start and end dates should be. Your example in 1 suggests the start year is constant, but it seems like that's not actually the case.
                      Last edited by Daniel Schaefer; 31 Oct 2024, 15:36.

                      Comment


                      • #12
                        See also https://journals.sagepub.com/doi/pdf...6867X211063415 for a tutorial review on loops in parallel in Stata.

                        Comment


                        • #13
                          Daniel Schaefer : Appreciate your help.

                          I used the grunfeld example bc people are familiar with it. My problem is not exactly the same. Figuring out the ranges for the loops (what you and Nick C helped with) is now resolved. The part that is unresolved is labeling the regressions using outreg2. Since the ranges do not have a common start/end/value, I need to put 2 values in a single cell and have not been able to do that thus far.

                          Once again, I very much appreciate your help.

                          If you have any insight as to how to resolve the issue I bring up here (writing 2 values to a single cell using outreg2 so I know what specification is which) and in the 9th post of this thread, I'd be grateful.

                          Happy Friday.

                          Comment


                          • #14
                            Nick Cox : Thanks for the link.

                            Comment


                            • #15
                              It doesn't look like outreg2 supports your needs. You can manipulate the excel table directly with the -putexcel- command. If no outreg2 answer is forthcoming, you can build the table dynamically with outreg2, then edit the specific cells you care to modify programmatically with -putexcel-.

                              Comment

                              Working...
                              X