Announcement

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

  • Storing outputs of multiple regressions run in loop in single dta file

    I am using a loop to run multiple mixed effect linear regression models, to see the effect of the same two independent variables on multiple dependent variables. Here is a sample of my data (it only includes a subset of the variables that I am using as dependent variables in the model):
    Code:
    * Example generated by -dataex-. For more info, type help dataex
    clear
    input float(form title1 rrate1) long(acad1 acad2 stat2 stat3)
    1 0 100 4 3 4 3
    1 0 100 4 1 1 1
    1 0 100 4 3 4 3
    1 0 100 4 3 4 .
    1 0 100 3 2 2 2
    1 0 100 4 4 4 4
    1 0 100 4 2 3 4
    1 0 100 4 4 4 4
    1 0 100 4 4 4 4
    1 0 100 3 4 2 2
    end
    Here is the loop I've written (I've used capture because some variables that start with acad have no observations for the subset of data specified by form==1):
    Code:
    foreach i of varlist acad* stat* {
        display "`i'"
        capture noisily mixed `i' i.title1 rrate1  if form==1 || school:
    }
    I would like to save the output of each regression in a dta file, with data looking something like this:
    DV name IV name Coeff SE z p
    acad1 title1 yes xxx xxx xx xx
    acad1 rrate1 xxx xxx xxx xx
    acad2 title1 yes xxx xxx xxx xxx
    acad2 rrate1 xxx xxx xxx xxx

    I've tried -statsby- (see below) but I don't think it can accomplish what I want, unless I'm not fully understanding what it's capable of. First, I don't actually need to run a regression for each value of the variable 'form' (I only need to run it for form==1) but statsby requires a grouping variable. Second, it ignores capture so I have to specify each variable so that the loop doesn't error out - ok, fine, I have to do some extra typing. Third, the save option only saves the output of each individual regression (although that's really more how the loop is written).

    Code:
    foreach i of varlist acad1 acad2 acad3 acad6 acad7 acad8 acad9 acad10 stat2 stat3 {
        display "`i'"
        statsby, by(form) saving(".do Files/Reporting/Insights Report/Working Files/myest.dta"): mixed `i' i.title1 rrate1 || school:
    }
    What I need is some way to append the results of each regression (ultimately, I will be running dozens of regressions) within the loop, so that only one dta file is created. I have done lots of searching and reading past posts, and I'm sure there is a solution but I haven't found one, at least one I could understand and translate to my situation - I am still relatively new to Stata.

    I am using Stata 17.
    Last edited by Emory Davis; 05 Jun 2023, 14:34.

  • #2
    I think this will do it. (Uses frames, so requires version 17 or later.)
    Code:
    frame create results str32(dv iv) float(b se z p)
    foreach v of varlist acad* stat* {
        mixed `v' i.title1 rrate1 if form == 1 || school:
        tempname M
        matrix `M' = r(table)
        foreach x in 1.title1 rrate1 {
            frame post results ("`v'") ("`x'") (`M'["b", "`v':`x'"]) ///
            (`M'["se", "`v':`x'"]) (`M'["z", "`v':`x'"]) (`M'["pvalue", "`v':`x'"])
        }
    }
    
    frame change results
    list, noobs clean
    Note: This code is untested as the example data provided does not support the analysis desired. If you find that this code gives error messages or is unsuitable, please include example data in which the proposed regressions can be carried out.
    Last edited by Clyde Schechter; 05 Jun 2023, 16:05.

    Comment


    • #3
      Clyde Schechter Thank you very much, with some minor adaptations for my data that worked perfectly. I will have to learn a little more about using frames now!

      Apologies for the error in my example data, I realize now I forgot to include the variable for my random effect. To help anyone that looks at this thread in the future, here is correct example data and the final code I used. I included one of the variables that has no observations for form==1, which accounts for why I added -capture- to the code.

      Code:
      * Example generated by -dataex-. For more info, type help dataex
      clear
      input float(form school title1 rrate1) long(acad1 acad2) double acad11 long(stat2 stat3)
      1 87 0 100 4 2 .a 4 2
      1 87 0 100 3 2 .a 2 2
      1 87 0 100 3 4 .a 3 3
      1 87 0 100 4 3 .a 3 4
      1 87 0 100 4 2 .a 2 3
      1 87 0 100 4 2 .a 3 3
      1 87 0 100 4 3 .a . 3
      1 87 0 100 3 3 .a 1 1
      1 87 0 100 4 2 .a 4 3
      1 87 0 100 4 3 .a 3 2
      1 87 0 100 4 2 .a 4 4
      1 87 0 100 3 3 .a 3 3
      1 87 0 100 3 3 .a . .
      1 87 0 100 3 3 .a 3 3
      1 87 0 100 3 2 .a 3 4
      end
      Code:
      frame create results str32(dv iv) float(b se z p) 
      foreach v of varlist acad* stat* {
          display "`v'"    // included so that if errors occur, can track which variable is causing it
          capture mixed `v' i.title1 rrate1 if form == 1 || school: 
          tempname M
          matrix `M' = r(table)
          foreach x in 1.title1 rrate1 {    // add outputs to frame
              capture frame post results ("`v'") ("`x'") (`M'["b", "`v':`x'"]) ///
              (`M'["se", "`v':`x'"]) (`M'["z", "`v':`x'"]) (`M'["pvalue", "`v':`x'"])
          }
      }
      
      frame change results
      list, noobs clean

      Comment

      Working...
      X