Announcement

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

  • Issues with Incorporating Locals and Scalars in esttab using Ben Jann's appendmodels

    Hello Statalist community,

    I am seeking help with an issue concerning the integration of local results and scalars using -esttab- with Ben Jann's (@Ben Jann) -appendmodels- in Stata. Although my code correctly performs estimations, the additional results managed through estadd are not reflected in the final outputs of -esttab- following the use of -appendmodels-. Here's a detailed description of my scenario and the related code:

    Issue Description:

    In my search for solutions on Statalist, I encountered a post by Andrew Musau that suggested adding an extra column for observations in esttab. However, my issue differs significantly. I need the added results like means and standard deviations to appear in the standard -esttab- rows where observations, fixed effects, and other statistics are typically displayed (after estimatios), not as an extra column. It seems that -appendmodels- does not retain these results added through -estadd-.

    Data used:

    This is a small sample of the data

    Code:
    * Example generated by -dataex-. For more info, type help dataex
    clear
    input double codmpio float(uriel_date23 uriel_totdenuncias uriel_corrup uriel_costre uriel_interv T_FB Treat_Ads Treat_Letter Treat_Letters)
    5001 1  41  4 5 3 . . . .
    5001 2 183 17 8 9 . . . .
    5001 3   1  0 0 0 . . . .
    5002 1   2  1 0 1 1 1 1 1
    5002 2   1  0 0 0 1 1 1 1
    5021 1   2  0 0 2 . . . .
    5021 2   4  1 0 1 . . . .
    5030 1  13  0 0 2 0 0 0 0
    5031 1   2  0 0 0 1 2 1 1
    5034 2  12  1 2 3 0 0 0 0
    5038 1   1  0 0 1 1 1 1 1
    5042 1   3  1 1 0 1 1 1 1
    5042 2   4  0 0 0 1 1 1 1
    5044 1   4  0 0 0 . . . .
    5045 1   5  0 0 1 . . . .
    5045 2   1  0 0 0 . . . .
    5051 1   9  0 0 2 1 2 2 3
    5055 1   4  0 0 2 1 3 1 1
    5055 2   1  0 0 0 1 3 1 1
    5079 1   9  0 0 1 1 2 2 3
    5079 2   8  3 1 3 1 2 2 3
    5079 3   1  0 0 0 1 2 2 3
    5086 2   1  0 0 1 . . . .
    5088 1  11  1 3 3 . . . .
    5088 2  41  5 0 0 . . . .
    5091 1   6  1 0 1 1 3 2 2
    5091 2   5  0 1 2 1 3 2 2
    5093 1   4  0 1 0 0 0 0 0
    5093 2  14  1 3 1 0 0 0 0
    5101 2   3  0 0 1 1 3 2 3
    5107 1   2  0 0 0 0 0 0 0
    5113 2   1  0 0 0 . . . .
    5113 3   1  0 0 0 . . . .
    5120 1   1  0 0 1 0 0 0 0
    5120 2   1  0 0 0 0 0 0 0
    5125 1   1  0 0 0 1 1 1 1
    5129 1   5  0 0 0 1 3 2 3
    5129 2   7  1 0 0 1 3 2 3
    5134 1   1  1 0 0 1 3 2 3
    5134 2   7  2 0 0 1 3 2 3
    5138 1   7  2 1 2 1 1 2 2
    5138 2   3  2 0 1 1 1 2 2
    5145 1   4  0 0 0 . . . .
    5145 2   1  0 0 0 . . . .
    5147 1  18  1 2 3 1 2 2 3
    5148 1  12  2 3 1 1 2 2 2
    5148 2  23  7 1 0 1 2 2 2
    5150 2   2  0 0 0 . . . .
    5154 1   2  0 0 0 1 1 2 2
    5154 2   2  0 0 0 1 1 2 2
    5172 1   2  0 1 0 1 3 2 3
    5172 2  13  1 0 0 1 3 2 3
    5190 2   6  1 0 1 1 3 2 2
    5197 1   1  0 0 0 1 2 2 2
    5197 2  10  3 0 0 1 2 2 2
    5206 1   5  0 0 0 . . . .
    5209 2   6  2 0 1 1 3 2 2
    5209 3   2  1 0 0 1 3 2 2
    5212 1   3  0 2 0 1 2 1 1
    5212 2   1  0 0 0 1 2 1 1
    5234 1   6  0 1 0 1 2 2 2
    5234 2   8  3 0 2 1 2 2 2
    5237 1   1  0 0 0 0 0 0 0
    5237 2   6  2 0 1 0 0 0 0
    5240 1   3  1 0 0 0 0 0 0
    5250 1  10  0 0 8 0 0 0 0
    5264 1   1  0 0 1 1 1 2 3
    5264 2   3  1 0 0 1 1 2 3
    5266 1   4  0 1 0 . . . .
    5266 2  30  2 5 2 . . . .
    5282 1  12  1 2 5 0 0 0 0
    5282 2   2  0 0 2 0 0 0 0
    5282 3   1  0 0 1 0 0 0 0
    5306 1   4  1 0 1 . . . .
    5308 1   4  0 0 4 . . . .
    5308 2  15  3 0 3 . . . .
    5310 1   1  0 0 0 0 0 0 0
    5310 2   1  0 0 0 0 0 0 0
    5313 1   1  0 0 0 1 1 2 2
    5313 2   1  0 0 0 1 1 2 2
    5318 1   7  0 0 1 1 2 2 3
    5318 2  15  2 0 0 1 2 2 3
    5321 1   7  1 2 3 . . . .
    5321 2   7  1 0 3 . . . .
    5347 1   5  0 0 2 . . . .
    5347 2   6  0 0 1 . . . .
    5353 1   7  1 1 1 . . . .
    5353 2   7  1 1 0 . . . .
    5360 1   6  0 1 1 . . . .
    5360 2  12  0 0 1 . . . .
    5361 1   3  0 0 0 1 1 2 2
    5368 1   7  1 2 4 1 2 2 2
    5376 1  17  2 1 3 1 1 2 3
    5376 2  12  2 0 2 1 1 2 3
    5380 1   6  0 0 0 1 1 2 2
    5380 2  19  2 0 2 1 1 2 2
    5380 3   1  0 0 0 1 1 2 2
    5390 1   3  1 0 0 . . . .
    5390 2  10  2 1 0 . . . .
    5400 2  11  0 0 0 1 1 2 2
    end

    Code:

    Code:
    gl uriel "uriel_totdenuncias uriel_corrup uriel_costre uriel_interv uriel_otros"
    
    foreach i of numli 1/3{
    * 4.1.1 Any treatment
    eststo clear
    foreach var of global uriel{
    
    * Defining lasso controls
    quietly: rlasso `var' $controls if uriel_date23 == `i', cluster(codmpio)
    local ySel `e(selected)'
    
    quietly: rlasso T_FB $controls if uriel_date23 == `i', cluster(codmpio)
    local xSel0 `e(selected)'
    
    local vSel : list ySel | xSel0
    
    * Estimation
    eststo `var'1: reg `var' T_FB `vSel' if uriel_date23 == `i', cluster(codmpio) coeflegend
    
    }
    
    
    * 4.1.2 Different ads
    
    foreach var of global uriel{
    
    * Defining lasso controls
    quietly: rlasso `var' $controls, cluster(codmpio)
    local ySel `e(selected)'
    
    quietly: rlasso T_FB $controls, cluster(codmpio)
    local xSel0 `e(selected)'
    
    quietly: rlasso T_FB_call $controls, cluster(codmpio)
    local xSel1 `e(selected)'
    
    quietly: rlasso T_FB_info $controls, cluster(codmpio)
    local xSel2 `e(selected)'
    
    quietly: rlasso T_FB_both $controls, cluster(codmpio)
    local xSel3 `e(selected)'
    
    local vSel : list ySel | xSel0
    local vSel : list vSel | xSel1
    local vSel : list vSel | xSel2
    local vSel : list vSel | xSel3
    
    * Estimation
    eststo `var'2: reg `var' i.Treat_Ads `vSel' if uriel_date23 == `i', cluster(codmpio) coeflegend
    
    }
    
    * 4.1.3 Letter - No Letter
    
    foreach var of global uriel{
    
    * Defining lasso controls
    quietly: rlasso `var' $controls, cluster(codmpio)
    local ySel `e(selected)'
    
    quietly: rlasso TT_FB $controls, cluster(codmpio)
    local xSel0 `e(selected)'
    
    quietly: rlasso T_Letter $controls, cluster(codmpio)
    local xSel1 `e(selected)'
    
    quietly: rlasso T_Letter_no_sj $controls, cluster(codmpio)
    local xSel2 `e(selected)'
    
    quietly: rlasso T_Letter_sj $controls, cluster(codmpio)
    local xSel3 `e(selected)'
    
    local vSel : list ySel | xSel0
    local vSel : list vSel | xSel1
    local vSel : list vSel | xSel2
    local vSel : list vSel | xSel3
    
    * Estimation
    eststo `var'3: reg `var' i.Treat_Letter `vSel' if uriel_date23 == `i', cluster(codmpio) coeflegend
    
    }
    
    * 4.1.4 Different Letters
    
    foreach var of global uriel{
    
    * Defining lasso controls
    quietly: rlasso `var' $controls, cluster(codmpio)
    local ySel `e(selected)'
    
    quietly: rlasso TT_FB $controls, cluster(codmpio)
    local xSel0 `e(selected)'
    
    quietly: rlasso T_Letter $controls, cluster(codmpio)
    local xSel1 `e(selected)'
    
    quietly: rlasso T_Letter_no_sj $controls, cluster(codmpio)
    local xSel2 `e(selected)'
    
    quietly: rlasso T_Letter_sj $controls, cluster(codmpio)
    local xSel3 `e(selected)'
    
    local vSel : list ySel | xSel0
    local vSel : list vSel | xSel1
    local vSel : list vSel | xSel2
    local vSel : list vSel | xSel3
    
    * Estimation
    eststo `var'4: reg `var' i.Treat_Letters `vSel' if uriel_date23 == `i', cluster(codmpio) coeflegend
    estadd ysumm
    sum `var' if e(sample) & T_FB == 0 & uriel_date23==`i'
    estadd local control_mean = r(mean)
    estadd local control_sd = r(sd)
    
    }
    
    eststo total: appendmodels uriel_totdenuncias1 uriel_totdenuncias2 uriel_totdenuncias3 ///
    uriel_totdenuncias4
    eststo corrup: appendmodels uriel_corrup1 uriel_corrup2 uriel_corrup3 uriel_corrup4
    eststo costre: appendmodels uriel_costre1 uriel_costre2 uriel_costre3 uriel_costre4
    eststo interv: appendmodels uriel_interv1 uriel_interv2 uriel_interv3 uriel_interv4
    eststo otros: appendmodels uriel_otros1 uriel_otros2 uriel_otros3 uriel_otros4
    
    
    esttab total corrup costre interv otros ///
    using "$results/uriel_results_group`i'.tex", replace ///
    keep(PanelA *T_FB PanelB *Treat_Ads PanelC *Treat_Letter PanelD *Treat_Letters) ///
    order (PanelA *T_FB PanelB *Treat_Ads PanelC *Treat_Letter PanelD *Treat_Letters) ///
    varlabels(PanelA "\textbf{Panel A: Pooled Treatment}" PanelB "\textbf{Panel B: Subtreatments by Types of Ads}" ///
    PanelC "\textbf{Panel C: Subtreatments by Letter - No Letter}" PanelD "\textbf{Panel D: Subtreatments by Types of Letters}") ///
    stats(N control_mean control_sd, labels( "N" "Control Mean DV" "Control SDDV") fmt(%9.0f %9.3f %9.3f))
    substitute("=1" "" "%" "\%" "_" "_") ///
    noomitted nobase label mti("\shortstack{Total\\Complaints}" "\shortstack{Voter\\Buying}" "\shortstack{Voter\\Intimidation}" "\shortstack{Political Intervention\\by Public Servants}" "\shortstack{Other\\Complaints}") addn( ///
    "\textbf{Notes:} We cluster at the student level. Number of observations is `obs'. * p$<$ 0.1, ** p$<$ 0.05, *** p$<$ 0.01") ///
    b(3) nonotes se star(* 0.10 ** 0.05 *** 0.01)
    
    }
    Table Output in LaTex using the.tex file :



    Request for Help:
    1. Has anyone managed to incorporate estadd results into the standard columns of esttab after using appendmodels?
    2. Are there alternative methods or settings that might ensure these results are preserved and displayed correctly in esttab?
    I appreciate any guidance or suggestions you might provide. Thank you very much in advance for your assistance!
    Last edited by Felipe Junco; 05 May 2024, 12:22.

  • #2
    I do not have much time to look into your example, but being that you reference statistics and appendmodels, I will use the example from https://www.statalist.org/forums/for...sults-together that uses the auto dataset. Hopefully it helps you.

    Code:
    sysuse auto.dta, clear
                
                *code to create multiple dummies as an example
                set seed 12345
                generate rannum = uniform()
                sort rannum
                gen grp1 = 1 in 1/25
                    replace grp1 = 0 if grp1 != 1
                gen grp2 = 1 in 26/50
                    replace grp2 = 0 if grp2 != 1
                gen grp3 = 1 in 51/74
                    replace grp2 = 0 if grp2 != 1
                
                eststo est1: mean price mpg rep78 [aweight= weight] if grp1 == 1
                eststo est2: mean price mpg rep78 [aweight= weight] if grp2 == 1
                eststo est3: mean price mpg rep78 [aweight= weight] if grp3 == 1
                eststo est4: reg price grp1 grp2 [aweight= weight], robust
                eststo est5: reg mpg grp1 grp2 [aweight= weight], robust
                eststo est6: reg rep78 grp1 grp2 [aweight= weight], robust
                
                local i 0
                forval e=4/6{
                    local ++i
                    est restore est`e'
                    margins, dydx(grp1) post
                    *RENAME COEFFICIENT
                    mat b=e(b)
                    local colname=cond(`e'==4, "price", cond(`e'==5, "mpg", "rep78"))
                    mat colname b= `colname'
                    erepost b=b, rename
                    est sto grp1_`i'
                    est restore est`e'
                    margins, dydx(grp2) post
                    *RENAME COEFFICIENT
                    mat b=e(b)
                    local colname=cond(`e'==4, "price", cond(`e'==5, "mpg", "rep78"))
                    mat colname b= `colname'
                    erepost b=b, rename
                    est sto grp2_`i'
                }
               
    
    *PROGRAM TO APPEND MODELS
    capt prog drop appendmodels
    *! version 1.0.0  14aug2007  Ben Jann
    program appendmodels, eclass
        // using first equation of model
        version 8
        syntax namelist
        tempname b V tmp
        foreach name of local namelist {
            qui est restore `name'
            mat `tmp' = e(b)
            local eq1: coleq `tmp'
            gettoken eq1 : eq1
            mat `tmp' = `tmp'[1,"`eq1':"]
            local cons = colnumb(`tmp',"_cons")
            if `cons'<. & `cons'>1 {
                mat `tmp' = `tmp'[1,1..`cons'-1]
            }
            mat `b' = nullmat(`b') , `tmp'
            mat `tmp' = e(V)
            mat `tmp' = `tmp'["`eq1':","`eq1':"]
            if `cons'<. & `cons'>1 {
                mat `tmp' = `tmp'[1..`cons'-1,1..`cons'-1]
            }
            capt confirm matrix `V'
            if _rc {
                mat `V' = `tmp'
            }
            else {
                mat `V' = ///
                ( `V' , J(rowsof(`V'),colsof(`tmp'),0) ) \ ///
                ( J(rowsof(`tmp'),colsof(`V'),0) , `tmp' )
            }
        }
        local names: colfullnames `b'
        mat coln `V' = `names'
        mat rown `V' = `names'
        eret post `b' `V'
        eret local cmd "whatever"
    end
    
    *APPEND THE MODELS
    eststo G1: appendmodels grp1_1 grp1_2 grp1_3
    eststo G2: appendmodels grp2_1 grp2_2 grp2_3
    
    *CREATE 2 LOCALS FOR EACH MODEL
    set seed 05052024
    forval i= 1/5{
        local stat`i'= rnormal()
    }
    
    *ASSIGN TO RESULTS
    estadd scalar stat=`stat1': G1
    estadd scalar stat=`stat2': G2
    
    esttab G1 G2, mlab(none) noobs stats(stat, fmt(%3.2f))

    Res.:

    Code:
    . esttab G1 G2, mlab(none) noobs stats(stat, fmt(%3.2f))
    
    --------------------------------------------
                          (1)             (2)   
    --------------------------------------------
    price               449.4           556.5   
                       (0.48)          (0.56)   
    
    mpg                 1.388           2.440   
                       (1.10)          (1.56)   
    
    rep78              -0.303           0.185   
                      (-1.03)          (0.65)   
    --------------------------------------------
    stat                -0.97            0.31   
    --------------------------------------------
    t statistics in parentheses
    * p<0.05, ** p<0.01, *** p<0.001

    Comment


    • #3
      Thank you for your quick response, Andrew!

      The reference you provided from the auto dataset example was exactly what I needed. I applied the proposed solution to my code, and it worked perfectly. I appreciate your help in pointing me in the right direction!

      Thank you once again for your valuable assistance!

      Comment

      Working...
      X