Announcement

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

  • Change degrees of freedom after estimating an OLS regression with sem

    Dear Stata experts,

    I recently learned how to change the degrees of freedom in the regress command using the dof() option (Thanks Trent Mize). This can be very handy when estimating a fixed effects model using the regress command with manually demeaned variables (example from Trent at the end of this post).

    I would like a way to change the df like this when estimating an OLS regression using sem. The dof() option is not available, and the two other strategies I tried have not worked yet:


    Strategy 1
    I can change the df after regress like this:

    mata: st_numscalar("e(df_r)", 21761)
    Unfortunately, this approach does not seem to update the t statistics or confidence intervals. I have not tried that approach yet with sem.

    Strategy 2
    It also looks like the df can also be changed with the ereturn repost command (see Stata Forum post), but I am not sure how to do that without deleting the b and V matrices.


    Does anyone know how to replicate the effect of the dof() option in a way that will work with sem?


    Thanks,

    Jeremy


    Code:
    webuse union, clear
    
    **************************************************************************    
    // #0 - Data Management
    **************************************************************************    
    
    drop if missing(union, age, grade, not_smsa, south, year)
    
    *Calculate person-specific means and demean the variables (subtract the person
    *specific mean from each so the new value represents the deviation from 
    *the subject-specific average)
    local ivs "union age grade not_smsa south year"
    foreach v in `ivs' {
        egen     `v'M = mean(`v'), by(idcode)
        gen     `v'D = `v' - `v'M
        }
        
    **************************************************************************    
    // #1 - Show normal FE model with xtreg
    **************************************************************************    
    xtset         idcode
    
    xtreg         grade age union i.not_smsa south c.year, fe
    est             store fixed
    
    
    **************************************************************************    
    // #2 - Use all demenaed vars (DV and IVs)
    **************************************************************************    
    *Fixed effects models using all demeaned vars    
    *Force df to be correct with dof() option (from FE models estimated earlier)
    reg         gradeD ageD unionD not_smsaD southD yearD,   dof(21761)
    est store    demean    
    
    ********************************
    *Compare the estimates
    ********************************
    esttab fixed demean, nobase noconstant

  • #2
    What -,dof- does can be achieved super easy by fiddling directly with the variance of the estimates, here:

    Code:
    . qui reg         gradeD ageD unionD not_smsaD southD yearD,   dof(21761)
    
    . matlist e(V)
    
                 |      ageD     unionD  not_smsaD     southD      yearD      _cons 
    -------------+------------------------------------------------------------------
            ageD |  .0002115                                                        
          unionD | -8.73e-07   .0001114                                             
       not_smsaD |  6.07e-07   7.06e-08   .0002794                                  
          southD | -3.32e-06   7.99e-06  -.0000215   .0003403                       
           yearD |  -.000213   6.62e-07  -8.09e-07   3.26e-06   .0002148            
           _cons | -4.11e-11   4.06e-13   1.29e-13   8.87e-13   4.15e-11   8.87e-06 
    
    . qui reg         gradeD ageD unionD not_smsaD southD yearD
    
    . matlist  e(df_r)*e(V)/21761
    
                 |      ageD     unionD  not_smsaD     southD      yearD      _cons 
    -------------+------------------------------------------------------------------
            ageD |  .0002115                                                        
          unionD | -8.73e-07   .0001114                                             
       not_smsaD |  6.07e-07   7.06e-08   .0002794                                  
          southD | -3.32e-06   7.99e-06  -.0000215   .0003403                       
           yearD |  -.000213   6.62e-07  -8.09e-07   3.26e-06   .0002148            
           _cons | -4.11e-11   4.06e-13   1.29e-13   8.87e-13   4.15e-11   8.87e-06

    Comment


    • #3
      Thank you Joro.

      To make the altered estimates available for esttab and other post estimation procedures, I used your formula with ereturn epost in a small eclass program (as explained here).

      I needed a slightly different version of the program for regress and sem because of the way the two commands store the degrees of freedom.

      Also, although the results with sem do not quite match the other exactly, I suspect that this is okay.
      The sem manual says, "When you estimate a linear regression by using sem, you obtain the same point estimates as you would with regress and the same standard errors up to a degree-of-freedom adjustment applied by regress."

      The updated code is below.

      Jeremy



      Code:
      webuse union, clear
      
      **************************************************************************    
      // #0 - Data Management
      **************************************************************************    
      
      drop if missing(union, age, grade, not_smsa, south, year)  // 0 obs deleted
      
      *Calculate person-specific means and demean the variables (subtract the person
      *specific mean from each so the new value represents the deviation from
      *the subject-specific average)
      local ivs "union age grade not_smsa south year"
      foreach v in `ivs' {
          egen     `v'M = mean(`v'), by(idcode)
          gen     `v'D = `v' - `v'M
          }
          
      **************************************************************************    
      // #1 - Show normal FE model with xtreg
      **************************************************************************    
      xtset         idcode
      
      xtreg         grade age union i.not_smsa south c.year, fe
      est             store fixed
      
      
      **************************************************************************    
      // #2 - Use all demeaned vars (DV and IVs)
      **************************************************************************    
      *Fixed effects models using all demeaned vars    
      *Force df to be correct with dof() option (from FE models estimated earlier)
      reg         gradeD ageD unionD not_smsaD southD yearD,   dof(21761)
      est store    dof    
      
      
      **************************************************************************    
      // My addition: try changing the df after estimation
      **************************************************************************    
      
      ******
      *put OLS df adjustment in eclass program
      ******
      cap prog drop olsdfadj
      prog olsdfadj, eclass
      matrix V = e(df_r)*e(V)/21761
      ereturn repost V = V
      end
      
      *use the program with regress
      reg         gradeD ageD unionD not_smsaD southD yearD
      olsdfadj
      est store olsdfadj
      
      ******
      *put SEM df adjustment in eclass program
      ******
      *There is no df_r with SEM so I take total df(i.e., N-1) - df_bs.
      
      cap prog drop semdfadj
      prog semdfadj, eclass
      matrix V = (e(N) -1 - e(df_bs))*e(V)/21761
      ereturn repost V = V
      end
      
      *use the program with SEM
      sem(gradeD <- ageD unionD not_smsaD southD yearD)
      semdfadj
      est store semdfadj
      
      ********************************
      *Compare the estimates
      ********************************
      esttab fixed dof olsdfadj semdfadj, ///
          cells(b se t) nobase noconstant mtitles(xtreg dof olsdfadj semdfadj) ///
          rename(ageD age unionD union not_smsaD 1.not_smsa southD south yearD year)
      
      
      ----------------------------------------------------------------
                            (1)          (2)          (3)          (4)
                          xtreg          dof     olsdfadj     semdfadj
                         b/se/t       b/se/t       b/se/t       b/se/t
      ----------------------------------------------------------------
      main                                                            
      age              .0087924     .0087924     .0087924     .0087924
                       .0145445     .0145445     .0145445     .0145428
                       .6045157     .6045157     .6045157      .604585
      union            .0259121     .0259121     .0259121     .0259121
                        .010556      .010556      .010556     .0105548
                       2.454731     2.454731     2.454731     2.455012
      1.not_smsa      -.0310558    -.0310558    -.0310558    -.0310558
                       .0167158     .0167158     .0167158     .0167138
                      -1.857876    -1.857876    -1.857876    -1.858089
      south           -.0225473    -.0225473    -.0225473    -.0225473
                       .0184467     .0184467     .0184467     .0184446
                      -1.222293    -1.222293    -1.222293    -1.222433
      year              .026098      .026098      .026098      .026098
                       .0146551     .0146551     .0146551     .0146534
                       1.780816     1.780816     1.780816      1.78102
      ----------------------------------------------------------------
      /                                                              
      var(e.grad~)                                            .1929986
                                                                .00185
                                                              104.3216
      ----------------------------------------------------------------
      N                   26200        26200        26200        26200
      ----------------------------------------------------------------
      Last edited by Jeremy Reynolds; 31 Jul 2020, 10:06.

      Comment


      • #4
        This is pretty nasty that one has to write a whole e-class programme just to change the e(V).

        Here is how one can trick -_robust- to do the same, without writing a whole e-class programme.

        Code:
        . qui xtreg         grade age union i.not_smsa south c.year, fe
        
        . est             store fixed
        
        . qui reg         gradeD ageD unionD not_smsaD southD yearD,   dof(21761)
        
        . est store    dof
        
        . qui reg         gradeD ageD unionD not_smsaD southD yearD
        
        . gen double e= sqrt(e(df_r))/e(rmse)/sqrt(21761)
        
        . _robust e, minus(6)
        
        . est sto myols
        
        . esttab fixed dof myols, cells(b se t) nobase noconstant rename(ageD age unionD union not_smsaD 1.n
        > ot_smsa southD south yearD year)
        
        ---------------------------------------------------
                              (1)          (2)          (3)
                            grade       gradeD       gradeD
                           b/se/t       b/se/t       b/se/t
        ---------------------------------------------------
        age              .0087924     .0087924     .0087924
                         .0145445     .0145445     .0145462
                         .6045157     .6045157     .6044465
        union            .0259121     .0259121     .0259121
                          .010556      .010556     .0105572
                         2.454731     2.454731      2.45445
        1.not_smsa      -.0310558    -.0310558    -.0310558
                         .0167158     .0167158     .0167177
                        -1.857876    -1.857876    -1.857663
        south           -.0225473    -.0225473    -.0225473
                         .0184467     .0184467     .0184488
                        -1.222293    -1.222293    -1.222153
        year              .026098      .026098      .026098
                         .0146551     .0146551     .0146568
                         1.780816     1.780816     1.780612
        ---------------------------------------------------
        N                   26200        26200        26200
        ---------------------------------------------------

        Comment

        Working...
        X