Announcement

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

  • esttab: displaying model across two columns

    Hi

    I would like to run a model like this:

    Code:
    webuse nlswork, clear
    
    eststo clear
    eststo: mixed ln_wage i.race##c.age nev_mar##c.age collgrad##c.age msp##c.age || idcode: age, cov(uns)
    
    esttab using table.rtf, replace label
    i.e. all right hand variables are come with an interaction term.

    As you will see, esttab (from SSC) creates a perfectly reasonable table. I would, however, would like to have a shorter table, and for that I would like to have the coefficients from the interaction terms in a separate column. In case this is not clear, I have made an example by hand:

    Click image for larger version

Name:	Screenshot 2025-05-07 153326.png
Views:	2
Size:	42.5 KB
ID:	1777039

    Is there any way for esttab to do this automatically?

    Thanks so much for your consideration!
    Go
    Attached Files

  • #2
    Thanks for the reproducible example. The issue here is that estout uses the column names of the e(b) and e(V) matrices to determine how the results are displayed. Since interactions are identified by the hash symbol, I tried a workaround: renaming the interaction terms to match the coefficients of the main effects and assigning them a separate equation name. Combined with esttab's -unstack- option, this appears to achieve the desired result. Below, note that erepost is from SSC.

    Code:
    webuse nlswork, clear
    mixed ln_wage i.race##c.age nev_mar##c.age collgrad##c.age msp##c.age || idcode: age, cov(uns)
    local names= ustrregexra("`:colnames e(b)'", "\b([0-9a-zA-Z\_\.]+)\#([0-9a-zA-Z\_\.]+)\b", "B:$1")
    mat b= e(b)
    mat V= e(V)
    mat colnames b= `names'
    mat colnames V= `names'
    erepost b=b V=V, rename
    eststo m1
    esttab m1, keep(`e(depvar)': B:) unstack ///
    eqlab("Main effect" "Interaction effect", lhs(Variables)) ///
    collab(none) nonumb mlab(none) modelwidth(20)
    Res.:

    Code:
    . esttab m1, keep(`e(depvar)': B:) unstack ///
    > eqlab("Main effect" "Interaction effect", lhs(Variables)) ///
    > collab(none) nonumb mlab(none) modelwidth(20)
    
    ------------------------------------------------------------
    Variables             Main effect      Interaction effect   
    ------------------------------------------------------------
    1.race                          0                       0   
                                  (.)                     (.)   
    
    2.race                    -0.0684*              -0.000893   
                              (-2.01)                 (-0.71)   
    
    3.race                    -0.0289                 0.00426   
                              (-0.20)                  (0.80)   
    
    age                        0.0167***                        
                              (14.96)                           
    
    0.nev_mar                       0                       0   
                                  (.)                     (.)   
    
    1.nev_mar                  -0.328***               0.0127***
                              (-8.43)                  (8.56)   
    
    0.collgrad                      0                       0   
                                  (.)                     (.)   
    
    1.collgrad                  0.150***              0.00756***
                               (3.51)                  (5.10)   
    
    0.msp                           0                       0   
                                  (.)                     (.)   
    
    1.msp                      0.0406                -0.00226*  
                               (1.31)                 (-2.18)   
    
    _cons                       1.143***                        
                              (34.82)                           
    ------------------------------------------------------------
    N                           28494                           
    ------------------------------------------------------------
    t statistics in parentheses
    * p<0.05, ** p<0.01, *** p<0.001

    Comment


    • #3
      Oh wow, this is exactly what I wanted! One issue I didn't see coming is: I actually need to have two models in my table:

      Code:
      webuse nlswork, clear
      eststo clear
      
      * Model 1
      mixed ln_wage age                                                     || idcode: age, cov(uns)
      eststo m1
      
      * Model 2
      mixed ln_wage i.race##c.age nev_mar##c.age collgrad##c.age msp##c.age || idcode: age, cov(uns)
      
      local names= ustrregexra("`:colnames e(b)'", "\b([0-9a-zA-Z\_\.]+)\#([0-9a-zA-Z\_\.]+)\b", "B:$1")
      mat b= e(b)
      mat V= e(V)
      mat colnames b= `names'
      mat colnames V= `names'
      erepost b=b V=V, rename
      eststo m2
      
      esttab m1 m2, keep(`e(depvar)': B:) unstack ///
      eqlab("Main effect" "Interaction effect", lhs(Variables)) ///
      collab(none) nonumb mlab(none) modelwidth(20)
      Is there a way to get esttab to produce acceptable output with two models in it?

      Thanks so much, you've been an incredible help already
      Go
      Last edited by Gobinda Natak; 08 May 2025, 14:06.

      Comment


      • #4
        I'm not sure what you mean by "acceptable", but if the issue is identifying models in #3, you can turn on the model labels. Otherwise, you must spell out how you want the output to appear.

        Code:
        webuse nlswork, clear
        eststo clear
        
        * Model 1
        mixed ln_wage age                                                     || idcode: age, cov(uns)
        eststo m1
        
        * Model 2
        mixed ln_wage i.race##c.age nev_mar##c.age collgrad##c.age msp##c.age || idcode: age, cov(uns)
        
        local names= ustrregexra("`:colnames e(b)'", "\b([0-9a-zA-Z\_\.]+)\#([0-9a-zA-Z\_\.]+)\b", "B:$1")
        mat b= e(b)
        mat V= e(V)
        mat colnames b= `names'
        mat colnames V= `names'
        erepost b=b V=V, rename
        eststo m2
        
        esttab m1 m2, keep(`e(depvar)': B:) unstack ///
        eqlab("Coef. (main)" "Coef. (interaction)", lhs(Variables)) ///
        mlab("Model 1 (no interactions)" "Model 2") /// 
        drop(_cons) collab(none) nobaselevels nonumb  modelwidth(25) label
        Res.:

        Code:
        . esttab m1 m2, keep(`e(depvar)': B:) unstack ///
        > eqlab("Coef. (main)" "Coef. (interaction)", lhs(Variables)) ///
        > mlab("Model 1 (no interactions)" "Model 2") /// 
        > drop(_cons) collab(none) nobaselevels nonumb  modelwidth(25) label
        
        -----------------------------------------------------------------------------------------------------------
                             Model 1 (no interactions)                      Model 2                                
        Variables                         Coef. (main)                 Coef. (main)          Coef. (interaction)   
        -----------------------------------------------------------------------------------------------------------
        Age in current year                     0.0208***                    0.0167***                             
                                               (36.70)                      (14.96)                                
        
        Black                                                               -0.0684*                   -0.000893   
                                                                            (-2.01)                      (-0.71)   
        
        Other                                                               -0.0289                      0.00426   
                                                                            (-0.20)                       (0.80)   
        -----------------------------------------------------------------------------------------------------------
        Observations                             28510                        28494                                
        -----------------------------------------------------------------------------------------------------------
        t statistics in parentheses
        * p<0.05, ** p<0.01, *** p<0.001

        Comment


        • #5
          My apologies (and thanks again!), I should have been clearer! When I run your code:

          Code:
          webuse nlswork, clear
          eststo clear
          
          * Model 1
          mixed ln_wage age                                                     || idcode: age, cov(uns)
          eststo m1
          
          * Model 2
          mixed ln_wage i.race##c.age nev_mar##c.age collgrad##c.age msp##c.age || idcode: age, cov(uns)
          
          local names= ustrregexra("`:colnames e(b)'", "\b([0-9a-zA-Z\_\.]+)\#([0-9a-zA-Z\_\.]+)\b", "B:$1")
          mat b= e(b)
          mat V= e(V)
          mat colnames b= `names'
          mat colnames V= `names'
          erepost b=b V=V, rename
          eststo m2
          
          esttab m1 m2, keep(`e(depvar)': B:) unstack ///
          eqlab("Coef. (main)" "Coef. (interaction)", lhs(Variables)) ///
          mlab("Model 1 (no interactions)" "Model 2") ///
          drop(_cons) collab(none) nobaselevels nonumb  modelwidth(25) label
          I get the Table displayed in your post, with two coefficients for race and one for age. But this is only part of the model? To go back to the top:

          Code:
          mixed ln_wage i.race##c.age nev_mar##c.age collgrad##c.age msp##c.age || idcode: age, cov(uns)
          The model also has two coefficients for marital status and one for education, what happens to those?

          Thanks so much
          Go

          Comment


          • #6
            Originally posted by Gobinda Natak View Post
            The model also has two coefficients for marital status and one for education, what happens to those?
            Looking at the issue, it appears to be caused by the order of the interaction terms in the results matrix. The quickest workaround I can suggest is to specify the main effects first in the command, followed by the interaction terms. For binary 0/1 variables, use "1.var" (with a 1. prefix) in the interaction instead of "i.var". For categorical variables with more than two categories, you can use "i.var", but note that interactions with the base level will be included. To avoid them being displayed, specify the -nobaselevels- option in esttab. Otherwise, you'll need to manually specify all non-base interactions if you want to display base levels in the table. The revised command line is highlighted below.



            Code:
            webuse nlswork, clear
            eststo clear
            
            * Model 1
            mixed ln_wage age || idcode: age, cov(uns)
            eststo m1
            
            * Model 2
            mixed ln_wage age i.race i.nev_mar i.collgrad i.msp i.race#c.age 1.nev_mar#c.age 1.collgrad#c.age 1.msp#c.age || idcode: age, cov(uns)
            
            local names= ustrregexra("`:colnames e(b)'", "\b([0-9a-zA-Z\_\.]+)\#([0-9a-zA-Z\_\.]+)\b", "B:$1")
            mat b= e(b)
            mat V= e(V)
            mat colnames b= `names'
            mat colnames V= `names'
            erepost b=b V=V, rename
            eststo m2
            
            esttab m1 m2, keep(`e(depvar)': B:) unstack  ///
            eqlab("Coef. (main)" "Coef. (interaction)", lhs(Variables)) ///
            mlab("Model 1" "Model 2") /// 
            drop(_cons) collab(none) nobaselevels nonumb  modelwidth(20) label
            Res.:

            Code:
            . esttab m1 m2, keep(`e(depvar)': B:) unstack  ///
            > eqlab("Coef. (main)" "Coef. (interaction)", lhs(Variables)) ///
            > mlab("Model 1" "Model 2") /// 
            > drop(_cons) collab(none) nobaselevels nonumb  modelwidth(20) label
            
            --------------------------------------------------------------------------------------------
                                              Model 1                 Model 2                           
            Variables                    Coef. (main)            Coef. (main)     Coef. (interaction)   
            --------------------------------------------------------------------------------------------
            Age in current year                0.0208***               0.0167***                        
                                              (36.70)                 (14.96)                           
            
            Black                                                     -0.0684*              -0.000893   
                                                                      (-2.01)                 (-0.71)   
            
            Other                                                     -0.0289                 0.00426   
                                                                      (-0.20)                  (0.80)   
            
            1 if never married=1                                       -0.328***               0.0127***
                                                                      (-8.43)                  (8.56)   
            
            1 if college gradu~1                                        0.150***              0.00756***
                                                                       (3.51)                  (5.10)   
            
            1 if married, spou~1                                       0.0406                -0.00226*  
                                                                       (1.31)                 (-2.18)   
            --------------------------------------------------------------------------------------------
            Observations                        28510                   28494                           
            --------------------------------------------------------------------------------------------
            t statistics in parentheses
            * p<0.05, ** p<0.01, *** p<0.001

            Comment

            Working...
            X