Announcement

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

  • Replacing coefficient with lincom estimate for esttab tables

    Hello Statalist, I have been grappling with how to replace a coefficient, standard error, and t-stat in xtscc regression results with lincom estimates prior to creating an esttab table. I am working with Stata version 15.1 and currently do not have the option to update, though I understand from here that more recent versions of Stata might make some of this easier by directly indexing "special" matrices for editing. I have found ways to edit the e(b) and e(V) matrices to replace the coefficient of interest with the lincom estimates, but it seems that the r(table) matrix is what I actually want to edit in order for it to show up in the esttab output. These were the posts I referred to initially when I thought that I wanted to edit the e(b) and e(V) matrices to affect the esttab output:
    https://www.stata.com/statalist/arch.../msg00054.html

    The basic code for one of the regressions and lincom is
    Code:
    * Regression
    xtscc fao_food_cpi_winsor kdd gdd c.kdd#c.l.agimp_sharegdp_baci i.country_code i.year, fe lag(5)
    estimates store prices_dom_kdd_impshare
    
    * Calculate median in-sample value for interacted term
    sum l.agimp_sharegdp_baci if _est_prices_dom_kdd_impshare, detail
    local impshare_median = r(p50)
    
    * Calculate aggregate effects for median import share
    lincom _b[kdd] + _b[c.kdd#c.l.agimp_sharegdp_baci]*`impshare_median'
    
    * Store results for use in wrapper
    scalar coef = r(estimate)
    scalar se = r(se)
    scalar t = r(t)
    What I would like to do is rather than have the kdd coefficient display the raw coefficient, have it display the aggregate effects, as calculated in the lincom command.

    The issue I am running into is that I am not sure how to go about editing r(table). From the link I included above, the only way I found to edit the matrices of the estimation results is as follows:
    Code:
    cap prog drop wrapper
    prog wrapper, eclass
    
    * Edit coefficient matrix
    matrix B = e(b)
    matrix B[1, 1] = coef
    ereturn repost b = B
    
    * Edit variance-covariance matrix
    matrix SE = e(V)
    matrix SE[1,1] = se^2
    ereturn repost V = SE
    end
    However, I cannot find an analog repost command for return, only ereturn. I am a little stuck now on how to proceed. I recognize that in newer versions I could probably just use:
    Code:
    matrix r(table)[1, 1] = coef
    but am unsure of what to do in version 15, where that triggers an error.

    I have created an example using the Stata dataset auto that I hope will help with reproducibility:
    Code:
    version 15.1
    sysuse auto, clear
    
    regress price mpg c.mpg#c.headroom
    estimates store example
    
    sum headroom if _est_example, de 
    local med_headroom = r(p50)
    lincom _b[mpg] + _b[c.mpg#c.headroom]*`med_headroom'
    scalar coef = r(estimate)
    scalar se = r(se)
    scalar t = r(t)
    estimates replay example
    Hopefully I am just missing something rather simple, but any assistance would be appreciated!

  • #2
    It seems to me that you want to have the main effect of kdd to refer to someone with median on ageimp. You don't have to modify your regression table. That is good because manually modifying regression tables is of course very dangerous. The trick is to first center ageimp at the median, and than use that centered variable instead of the uncentered one. Centering is just subtract the median from ageimp.
    ---------------------------------
    Maarten L. Buis
    University of Konstanz
    Department of history and sociology
    box 40
    78457 Konstanz
    Germany
    http://www.maartenbuis.nl
    ---------------------------------

    Comment


    • #3
      Hi Maarten, I understand the concerns modifying a regression table, but I am not sure if that is what we want. My impression would be that doing this centering procedure would get the kdd coefficient estimate we want (though I would have to make sure I am calculating the median over the would-be sample, I believe), but we also want to retain the separate interacted effects in the table as-is. I am not sure I immediately see how centering would affect the coefficient on the kdd#agimp interacted term. I would have to think if the kdd coefficient will change with the centering, then the interacted regression term will also change. It isn't really up to me what is displayed here, so while I appreciate thoughts on changing the regressions themselves, that decision is a little over my head.

      Edited to add: I tested it and I can see that it actually does not change any of the other coefficients, which I guess does make sense now that I think about it a bit more. Now I just need to figure out the most efficient way to create a flag to make sure I am calculating the median over the desired sample prior to running the regressions. I would still be curious about a solution to the original problem I posted, though, since I don't want my only option to be to estadd scalars to the bottom of a table should I ever want to add something to the coefficient section of the table in the future.
      Last edited by Stephanie Stewart; 29 Mar 2025, 08:56.

      Comment


      • #4
        Originally posted by Stephanie Stewart View Post
        My impression would be that doing this centering procedure would get the kdd coefficient estimate we want (though I would have to make sure I am calculating the median over the would-be sample, I believe), but we also want to retain the separate interacted effects in the table as-is.
        Why? The interaction effects without centering aren't wrong per se, but they are often meaningless. The interaction effect with centering contain the exact same information, but in a meaningful way. There is literally no added value in adding the coefficients without centering, but it does make your table harder to read. A cost without a benefit seems to me just a really bad idea.

        Originally posted by Stephanie Stewart View Post
        I am not sure I immediately see how centering would affect the coefficient on the kdd#agimp interacted term.
        It does not change the coefficient of the interaction term.

        Originally posted by Stephanie Stewart View Post
        It isn't really up to me what is displayed here
        You have my sympathy.

        Originally posted by Stephanie Stewart View Post
        I tested it and I can see that it actually does not change any of the other coefficients
        Than you made an error. Lets first go through what we expect and than go through an example. So we have a regression like this:

        \(\hat{y} = \beta_0 + \beta_1 x_1 + \beta_2 x_2 + \beta_3 x_1 \times x_2 + \beta_4 x_3 \)

        \(x_1\) and \(x_2\) are interacted. We can see that the effect of \(x_1\) on \(\hat{y}\) is \(\beta_1 + \beta_3 x_2\) so \(\beta_1\) is the effect of \(x_1\) when \(x_2\) is 0. So when we center \(x_2\), that will change the effect of \(x_1\) but not the effect of \(x_2\). Centering will also change the constant (the predicted \(y\) when all \(x\)s are zero.

        Here is an example. In this case we are interacting weight with mpg and centering weight. The coefficient of mpg is the effect of mpg when weight is 0. Without centering a weight of 0 means a very unrealistically light car, but after centering the value 0 corresponds to a care of median weight. So the main effect of mpg changes when centering weight. The effect of weight itself, and the interaction effect and the effects of other explanatory variable (in this case foreign) remain unchanged. The only other coefficient that changes is the constant.

        Code:
        . // open example data
        . sysuse auto , clear
        (1978 automobile data)
        
        .
        . // estimate a model without centering
        . qui reg price c.mpg##c.weight i.foreign
        
        . est store a
        
        .
        . // center the weight variable
        . qui sum weight if !missing(price,mpg,foreign), detail
        
        . gen weight_c = weight - r(p50)
        
        .
        . // use the weight variable
        . qui reg price c.mpg##c.weight_c i.foreign
        
        . est store b
        
        .
        . // compare models
        . est table a b
        
        ----------------------------------------
            Variable |     a            b       
        -------------+--------------------------
                 mpg |  292.82954   -86.498919  
              weight |  5.3827546               
                     |
               c.mpg#|
            c.weight | -.11891174               
                     |
             foreign |
            Foreign  |  3369.8145    3369.8145  
                     |
            weight_c |               5.3827546  
                     |
               c.mpg#|
          c.weight_c |              -.11891174  
                     |
               _cons | -10105.039    7065.9482  
        ----------------------------------------
        ---------------------------------
        Maarten L. Buis
        University of Konstanz
        Department of history and sociology
        box 40
        78457 Konstanz
        Germany
        http://www.maartenbuis.nl
        ---------------------------------

        Comment


        • #5
          Hi Maarten, thank you again for your help. I said
          I tested it and I can see that it actually does not change any of the other coefficients
          (the other coefficients being the interaction terms). You said
          It does not change the coefficient of the interaction term.
          Where did I make a mistake? It seems like the other coefficients should not change, and they did not change. I was adding the information because my knee-jerk reaction was that they would, but they didn't, and, as I said, upon further reflection, this makes sense.

          Why? The interaction effects without centering aren't wrong per se, but they are often meaningless. The interaction effect with centering contain the exact same information, but in a meaningful way. There is literally no added value in adding the coefficients without centering, but it does make your table harder to read. A cost without a benefit seems to me just a really bad idea.
          Again, I think there has been a misunderstanding. In the case of the regression I posted above, the table would only have coefficients for KDD, GDD, and the interacted term KDD × Import Share. The question was how to change the KDD coefficient to evaluate effects at the median, which you pointed out could be achieved by centering. The entire problem was that the coefficient did not have a useful interpretation. We never intended to show both the centered and uncentered coefficient.

          I am still curious about any ways to manipulate r(table), if anyone is willing to share this information. I have proceeded with this decentering approach, but at this point I am just curious if this is even possible.

          Comment


          • #6
            Thanks for including a reproducible example, Stephanie. However, it doesn't continue far enough to actually reproduce the issue, it only lays the foundation. Can you share a reproducible example including the esttab command, and mention exactly which value is unexpected, together with your expectation for that value? When I glue together some of your code and run it on version 18.5:

            Code:
            version 15.1
            
            cap prog drop wrapper
            prog wrapper, eclass
            
            * Edit coefficient matrix
            matrix B = e(b)
            matrix B[1, 1] = coef
            ereturn repost b = B
            
            * Edit variance-covariance matrix
            matrix SE = e(V)
            matrix SE[1,1] = se^2
            ereturn repost V = SE
            end
            
            sysuse auto, clear
            
            regress price mpg c.mpg#c.headroom
            estimates store example
            
            sum headroom if _est_example, de 
            local med_headroom = r(p50)
            lincom _b[mpg] + _b[c.mpg#c.headroom]*`med_headroom'
            scalar coef = r(estimate)
            scalar se = r(se)
            scalar t = r(t)
            estimates replay example
            
            wrapper
            
            esttab example .
            I get this result:

            Code:
            . esttab example .
            
            --------------------------------------------
                                  (1)             (2)   
                                price           price   
            --------------------------------------------
            mpg                -208.7**        -265.3***
                              (-3.40)         (-4.46)   
            
            c.mpg#c.he~m       -18.87          -18.87   
                              (-0.99)         (-0.99)   
            
            _cons             11774.2***      11774.2***
                               (9.16)          (9.16)   
            --------------------------------------------
            N                      74              74   
            --------------------------------------------
            t statistics in parentheses
            * p<0.05, ** p<0.01, *** p<0.001
            What does it look like for you on 15.1? Is it what you expect? I think I can get things working on 15.1, but I don't want to dig much deeper until I know exactly what I'm looking for.

            Comment


            • #7
              Hi Nils, thanks for your response. I think I realized perhaps what was happening and why the program wrapper wasn't changing the table for me. For some reason, I thought that
              Code:
              ereturn repost b = B
              Was editing the estimates stored in example without having to run
              Code:
              estimates store example
              again. So, when I created the table using
              Code:
              esttab example //without including a period
              I was only seeing the first column. With hindsight, it is obvious that repost would only be editing the current results, not what is stored under example. I see now that if I run
              Code:
              version 15.1
              
              cap prog drop wrapper
              prog wrapper, eclass
              
              * Edit coefficient matrix
              matrix B = e(b)
              matrix B[1, 1] = coef
              ereturn repost b = B
              
              * Edit variance-covariance matrix
              matrix SE = e(V)
              matrix SE[1,1] = se^2
              ereturn repost V = SE
              end
              
              sysuse auto, clear
              
              regress price mpg c.mpg#c.headroom
              estimates store example
              
              sum headroom if _est_example, de 
              local med_headroom = r(p50)
              lincom _b[mpg] + _b[c.mpg#c.headroom]*`med_headroom'
              scalar coef = r(estimate)
              scalar se = r(se)
              scalar t = r(t)
              
              wrapper
              estimates store example
              
              esttab example
              I get what I wanted using the original method. It seems the issue arose from my misunderstanding ereturn repost. Thanks for helping me correctly identify the source of my problem!

              Comment

              Working...
              X