Tabulating a Stata matrix

A Stata matrix can be tabulated in estout or esttab by typing matrix(matname) instead of providing a list of names of stored estimation sets. Example:

. matrix A = (11,12,13)\(21,22,23)\(31,32,33)\(41,42,43)

. esttab matrix(A)

---------------------------------------------------
                        A                          
                       c1           c2           c3
---------------------------------------------------
r1                     11           12           13
r2                     21           22           23
r3                     31           32           33
r4                     41           42           43
---------------------------------------------------
Code

Numeric formats can be set by adding a fmt() suboption in the matrix() argument. Examples:

. esttab matrix(A, fmt(1 2 3))

---------------------------------------------------
                        A                          
                       c1           c2           c3
---------------------------------------------------
r1                   11.0        12.00       13.000
r2                   21.0        22.00       23.000
r3                   31.0        32.00       33.000
r4                   41.0        42.00       43.000
---------------------------------------------------

. esttab matrix(A, fmt("1 2 3 4" "4 3 2 1"))

---------------------------------------------------
                        A                          
                       c1           c2           c3
---------------------------------------------------
r1                   11.0      12.0000         13.0
r2                  21.00       22.000        23.00
r3                 31.000        32.00       33.000
r4                41.0000         42.0      43.0000
---------------------------------------------------
Code

Examples for tabulating a matrix that also contains equation names:

. mat rownames A = "eq1:row1" "eq1:row2" "eq2:row1" "eq2:row2"

. esttab matrix(A)

---------------------------------------------------
                        A                          
                       c1           c2           c3
---------------------------------------------------
eq1                                                
row1                   11           12           13
row2                   21           22           23
---------------------------------------------------
eq2                                                
row1                   31           32           33
row2                   41           42           43
---------------------------------------------------

. esttab matrix(A), unstack compress

----------------------------------------------------------------------
                   A                                                  
                 eq1                           eq2                    
                  c1        c2        c3        c1        c2        c3
----------------------------------------------------------------------
row1              11        12        13        31        32        33
row2              21        22        23        41        42        43
----------------------------------------------------------------------

. set seed 123

. matrix A = matuniform(4,4)

. mat coleq A = eq1 eq1 eq2 eq2

. mat roweq A = eq1 eq1 eq2 eq2

. esttab matrix(A), eqlabels(,merge)

----------------------------------------------------------------
                        A                                       
                   eq1:c1       eq1:c2       eq2:c3       eq2:c4
----------------------------------------------------------------
eq1:r1           .3132002     .5559791     .9382851     .7363221
eq1:r2           .1924076     .1951401     .9509598     .2904454
eq2:r3           .8190824     .4882096     .2704866     .5859706
eq2:r4           .0539035     .5583192     .6395468      .974769
----------------------------------------------------------------
Code
[top]

More on correlation coefficients

[See Correlation coefficients for some basic examples on tabulating correlation coefficients with estpost.]

Kelvin Tan asked on statalist (see here): "I would like to know if I can stack two correlation matrix tables into one big correlation matrix ((foreign=1) in lower diagonal and (foreign=0) in upper diagonal of the big correlation matrix table)." Maarten Buis suggested a solution that works for the coefficients but does not provide significance stars or p-values (see here). Here are some examples for combining correlation coefficients while preserving the p-values. If you just want to stack two correlation matrices, you could code:

. sysuse auto, clear
(1978 Automobile Data)

. local vlist price mpg weight

. local rest `vlist'

. foreach v of local vlist {
  2.     estpost correlate `v' `rest' if foreign==0
  3.     foreach m in b rho p count {
  4.         matrix tmp = e(`m')
  5.         matrix coleq tmp = "foreign=0"
  6.         matrix `m' = tmp
  7.     }
  8.     estpost correlate `v' `rest' if foreign==1
  9.     foreach m in b rho p count {
 10.         matrix tmp = e(`m')
 11.         matrix coleq tmp = "foreign=1"
 12.         matrix `m' = `m', tmp
 13.     }
 14.     ereturn post b
 15.     foreach m in rho p count {
 16.         quietly estadd matrix `m' = `m'
 17.     }
 18.     eststo `v'
 19.     local rest: list rest - v
 20. }

       price |      e(b)     e(rho)       e(p)   e(count) 
-------------+--------------------------------------------
       price |         1          1                    52 
         mpg | -.5042629  -.5042629   .0001381         52 
      weight |  .6723974   .6723974   4.79e-08         52 

       price |      e(b)     e(rho)       e(p)   e(count) 
-------------+--------------------------------------------
       price |         1          1                    22 
         mpg | -.6313026  -.6313026    .001628         22 
      weight |   .885529    .885529   4.31e-08         22 

         mpg |      e(b)     e(rho)       e(p)   e(count) 
-------------+--------------------------------------------
         mpg |         1          1                    52 
      weight | -.8759427  -.8759427   1.89e-17         52 

         mpg |      e(b)     e(rho)       e(p)   e(count) 
-------------+--------------------------------------------
         mpg |         1          1                    22 
      weight |  -.682854   -.682854   .0004617         22 

      weight |      e(b)     e(rho)       e(p)   e(count) 
-------------+--------------------------------------------
      weight |         1          1                    52 

      weight |      e(b)     e(rho)       e(p)   e(count) 
-------------+--------------------------------------------
      weight |         1          1                    22 

. esttab, nonumbers mtitles noobs not

------------------------------------------------------------
                    price             mpg          weight   
------------------------------------------------------------
foreign=0                                                   
price                   1                                   
mpg                -0.504***            1                   
weight              0.672***       -0.876***            1   
------------------------------------------------------------
foreign=1                                                   
price                   1                                   
mpg                -0.631**             1                   
weight              0.886***       -0.683***            1   
------------------------------------------------------------
* p<0.05, ** p<0.01, *** p<0.001

. eststo clear
Code

The trick is to save a separate estimation set for each column of the correlation matrix and use equation names for the two groups.

Kelvin's upper/lower triangle layout can be achieved using a similar approach:

. sysuse auto, clear
(1978 Automobile Data)

. local vlist price mpg weight

. local upper

. local lower `vlist'

. foreach v of local vlist {
  2.     estpost correlate `v' `lower' if foreign==1
  3.     foreach m in b rho p count {
  4.         matrix `m' = e(`m')
  5.     }
  6.     if "`upper'"!="" {
  7.         estpost correlate `v' `upper' if foreign==0
  8.         foreach m in b rho p count {
  9.             matrix `m' = e(`m'), `m'
 10.         }
 11.     }
 12.     ereturn post b
 13.     foreach m in rho p count {
 14.         quietly estadd matrix `m' = `m'
 15.     }
 16.     eststo `v'
 17.     local lower: list lower - v
 18.     local upper `upper' `v'
 19. }

       price |      e(b)     e(rho)       e(p)   e(count) 
-------------+--------------------------------------------
       price |         1          1                    22 
         mpg | -.6313026  -.6313026    .001628         22 
      weight |   .885529    .885529   4.31e-08         22 

         mpg |      e(b)     e(rho)       e(p)   e(count) 
-------------+--------------------------------------------
         mpg |         1          1                    22 
      weight |  -.682854   -.682854   .0004617         22 

         mpg |      e(b)     e(rho)       e(p)   e(count) 
-------------+--------------------------------------------
       price | -.5042629  -.5042629   .0001381         52 

      weight |      e(b)     e(rho)       e(p)   e(count) 
-------------+--------------------------------------------
      weight |         1          1                    22 

      weight |      e(b)     e(rho)       e(p)   e(count) 
-------------+--------------------------------------------
       price |  .6723974   .6723974   4.79e-08         52 
         mpg | -.8759427  -.8759427   1.89e-17         52 

. esttab, nonumbers mtitles noobs not

------------------------------------------------------------
                    price             mpg          weight   
------------------------------------------------------------
price                   1          -0.504***        0.672***
mpg                -0.631**             1          -0.876***
weight              0.886***       -0.683***            1   
------------------------------------------------------------
* p<0.05, ** p<0.01, *** p<0.001

. eststo clear
Code
[top]

Flip models and coefficients

esttab and estout place different models in separate columns. Sometimes it is desirable, however, to arrange a table so that the models are placed in separate rows. Here are two approaches to construct such a table.

Approach 1

esttab and estout return a matrix r(coefs) that contains the tabulated results. You can run esttab or estout and then run it again in matrix mode to transpose and tabulate r(coefs). This approach is simple but the possibilities for formatting the table are somewhat limited. Example:

. sysuse auto, clear
(1978 Automobile Data)

. eststo model1: quietly reg price weight

. eststo model2: quietly reg price weight mpg

. esttab, se nostar

--------------------------------------
                      (1)          (2)
                    price        price
--------------------------------------
weight              2.044        1.747
                  (0.377)      (0.641)

mpg                             -49.51
                               (86.16)

_cons              -6.707       1946.1
                 (1174.4)     (3597.0)
--------------------------------------
N                      74           74
--------------------------------------
Standard errors in parentheses

. mat list r(coefs)

r(coefs)[3,4]
            model1:     model1:     model2:     model2:
                 b          se           b          se
weight   2.0440626   .37683413   1.7465592   .64135379
   mpg          .z          .z  -49.512221   86.156039
 _cons  -6.7073534   1174.4296   1946.0687   3597.0496

. esttab r(coefs, transpose)

---------------------------------------------------
                 r(coefs)                          
                   weight          mpg        _cons
---------------------------------------------------
model1                                             
b                2.044063                 -6.707353
se               .3768341                   1174.43
---------------------------------------------------
model2                                             
b                1.746559    -49.51222     1946.069
se               .6413538     86.15604      3597.05
---------------------------------------------------

. eststo clear
Code
[top]

Approach 2

Again run esttab or estout to compile r(coefs) but then, for each coefficient, collect the results and post them in e() (i.e. post one "model" per coefficient). This approach requires some programming but gives you full flexibility. Example:

. sysuse auto, clear
(1978 Automobile Data)

. eststo model1: quietly reg price weight

. eststo model2: quietly reg price weight mpg

. esttab, se nostar

--------------------------------------
                      (1)          (2)
                    price        price
--------------------------------------
weight              2.044        1.747
                  (0.377)      (0.641)

mpg                             -49.51
                               (86.16)

_cons              -6.707       1946.1
                 (1174.4)     (3597.0)
--------------------------------------
N                      74           74
--------------------------------------
Standard errors in parentheses

. matrix C = r(coefs)

. eststo clear

. local rnames : rownames C

. local models : coleq C

. local models : list uniq models

. local i 0

. foreach name of local rnames {
  2.     local ++i
  3.     local j 0
  4.     capture matrix drop b
  5.     capture matrix drop se
  6.     foreach model of local models {
  7.         local ++j
  8.         matrix tmp = C[`i', 2*`j'-1]
  9.         if tmp[1,1]<. {
 10.             matrix colnames tmp = `model'
 11.             matrix b = nullmat(b), tmp
 12.             matrix tmp[1,1] = C[`i', 2*`j']
 13.             matrix se = nullmat(se), tmp
 14.         }
 15.     }
 16.     ereturn post b
 17.     quietly estadd matrix se
 18.     eststo `name'
 19. }

. esttab, se mtitle noobs

------------------------------------------------------------
                      (1)             (2)             (3)   
                   weight             mpg           _cons   
------------------------------------------------------------
model1              2.044***                       -6.707   
                  (0.377)                        (1174.4)   

model2              1.747**        -49.51          1946.1   
                  (0.641)         (86.16)        (3597.0)   
------------------------------------------------------------
Standard errors in parentheses
* p<0.05, ** p<0.01, *** p<0.001

. eststo clear
Code

Approach 2 with summary statistics:

. sysuse auto, clear
(1978 Automobile Data)

. eststo model1: quietly reg price weight

. eststo model2: quietly reg price weight mpg

. esttab, se nostar r2

--------------------------------------
                      (1)          (2)
                    price        price
--------------------------------------
weight              2.044        1.747
                  (0.377)      (0.641)

mpg                             -49.51
                               (86.16)

_cons              -6.707       1946.1
                 (1174.4)     (3597.0)
--------------------------------------
N                      74           74
R-sq                0.290        0.293
--------------------------------------
Standard errors in parentheses

. matrix C = r(coefs)

. matrix S = r(stats)

. eststo clear

. local rnames : rownames C

. local models : coleq C

. local models : list uniq models

. local i 0

. foreach name of local rnames {
  2.     local ++i
  3.     local j 0
  4.     capture matrix drop b
  5.     capture matrix drop se
  6.     foreach model of local models {
  7.         local ++j
  8.         matrix tmp = C[`i', 2*`j'-1]
  9.         if tmp[1,1]<. {
 10.             matrix colnames tmp = `model'
 11.             matrix b = nullmat(b), tmp
 12.             matrix tmp[1,1] = C[`i', 2*`j']
 13.             matrix se = nullmat(se), tmp
 14.         }
 15.     }
 16.     ereturn post b
 17.     quietly estadd matrix se
 18.     eststo `name'
 19. }

. local snames : rownames S

. local i 0

. foreach name of local snames {
  2.     local ++i
  3.     local j 0
  4.     capture matrix drop b
  5.     foreach model of local models {
  6.         local ++j
  7.         matrix tmp = S[`i', `j']
  8.         matrix colnames tmp = `model'
  9.         matrix b = nullmat(b), tmp
 10.     }
 11.     ereturn post b
 12.     eststo `name'
 13. }

. esttab, se mtitle noobs compress nonumb

---------------------------------------------------------------------------
              weight          mpg        _cons            N           r2   
---------------------------------------------------------------------------
model1         2.044***                 -6.707           74        0.290   
             (0.377)                  (1174.4)                             

model2         1.747**     -49.51       1946.1           74        0.293   
             (0.641)      (86.16)     (3597.0)                             
---------------------------------------------------------------------------
Standard errors in parentheses
* p<0.05, ** p<0.01, *** p<0.001

. eststo clear
Code
[top]

Results from r-class program

Many Stata commands and user programs return results in r(). To tabulate such results in estout or esttab you can collect them in a matrix and tabulate the matrix (Approach 1) or post the results as one or more vectors in e() and tabulate them from there (Approach 2). Approach 2 is more flexible than Approach 1.

Approach 1: collect results in a matrix and tabulate the matrix

In the following example the ineqrbd command by Carlo V. Fiorio and Stephen P. Jenkins is used (see http://ideas.repec.org/c/boc/bocode/s456960.html). ineqrbd happens to return results in a series of r()-macros. We can construct a matrix from these macros (and also compute some additional results using the formulas provided in ineqrbd's output) and then tabulate the matrix as follows:

. capture which ineqrbd      // check whether -ineqrbd- is installed

. if _rc ssc install ineqrbd // and get it if not

. sysuse auto, clear
(1978 Automobile Data)

. ineqrbd price trunk weight length foreign, noregression
 
Regression-based decomposition of inequality in  price
---------------------------------------------------------------------------
Decomp.  |     100*s_f        S_f     100*m_f/m      CV_f   CV_f/CV(total)
---------+-----------------------------------------------------------------
residual |     45.1031      0.2158      0.0000    1.79e+15    3.74e+15
trunk    |     -0.4687     -0.0022     -2.2943     -0.3109     -0.6499
weight   |     81.8711      0.3917    282.5215      0.2574      0.5380
length   |    -29.2268     -0.1398   -273.2854     -0.1185     -0.2477
foreign  |      2.7213      0.0130     17.2635      1.5479      3.2356
---------+-----------------------------------------------------------------
Total    |    100.0000      0.4784    100.0000      0.4784      1.0000
---------------------------------------------------------------------------
Note: proportionate contribution of composite var f to inequality of Total,
      s_f = rho_f*sd(f)/sd(Total). S_f = s_f*CV(Total).
      m_f = mean(f). sd(f) = std.dev. of f. CV_f = sd(f)/m_f.
      Total = price

. return list

macros:
              r(sf_Z4) : ".0272132003266729"
              r(cv_Z4) : "1.547906632830336"
              r(sd_Z4) : "1647.497942176796"
            r(mean_Z4) : "1064.339351763328"
              r(sf_Z3) : "-.2922677469661964"
              r(cv_Z3) : "-.1184805603472781"
              r(sd_Z3) : "1996.248597028214"
            r(mean_Z3) : "-16848.7437194508"
              r(sf_Z2) : ".8187108270390759"
              r(cv_Z2) : ".2573949336205026"
              r(sd_Z2) : "4483.350954895487"
            r(mean_Z2) : "17418.17871794493"
              r(sf_Z1) : "-.004687100101882"
              r(cv_Z1) : "-.3109311493112151"
              r(sd_Z1) : "43.98088549818675"
            r(mean_Z1) : "-141.4489529132564"
              r(sf_Z0) : ".4510308197023296"
              r(cv_Z0) : "1790770538833059"
              r(sd_Z0) : "1980.84687222313"
            r(mean_Z0) : "1.10614220486e-12"
             r(cv_tot) : ".4784060098610566"
             r(sd_tot) : "2949.495884768919"
           r(mean_tot) : "6165.256756756757"
              r(total) : " price"
              r(xvars) : "trunk weight length foreign"
               r(yvar) : "price"
            r(varlist) : "price trunk weight length foreign"

. // Step 1: collect results from r(sf_Z#), r(mean_Z#), and r(cv_Z#)
. local xvars "`r(xvars)'"

. local nx : list sizeof xvars

. foreach s in sf mean cv {
  2.    tempname `s'
  3.    matrix ``s'' = J(`nx'+2, 1, .z)
  4.    matrix rownames ``s'' = residual `r(xvars)' Total
  5.    forv i = 0/`nx' {
  6.        matrix ``s''[`i'+1, 1] = `r(`s'_Z`i')'
  7.    }
  8. }

. matrix `sf'[rowsof(`sf'), 1]     = 1

. matrix `mean'[rowsof(`mean'), 1] = `r(mean_tot)'

. matrix `cv'[rowsof(`sf'), 1]     = `r(cv_tot)'

. // Step 2: build matrix that mirrors -ineqrbd-'s output
. matrix ineqrbd = ///
>    `sf' * 100 ,                    /// column 1: 100*s_f
>    `sf' * `r(cv_tot)' ,            /// column 2: S_f
>    `mean' / `r(mean_tot)' * 100,   /// column 3: 100*m_f/m
>    `cv',                           /// column 4: CV_f
>    `cv' / `r(cv_tot)'              //  column 5: CV_f/CV(total)

. matrix colnames ineqrbd = 100*s_f S_f 100*m_f/m CV_f CV_f/CV(total)

. // Step 3: tabulate the matrix
. esttab matrix(ineqrbd)

-----------------------------------------------------------------------------
                  ineqrbd                                                    
                  100*s_f          S_f    100*m_f/m         CV_f CV_f/CV(to~)
-----------------------------------------------------------------------------
residual         45.10308     .2157759     1.79e-14     1.79e+15     3.74e+15
trunk             -.46871    -.0022423    -2.294291    -.3109311    -.6499315
weight           81.87108     .3916762     282.5215     .2573949     .5380261
length          -29.22677    -.1398226    -273.2854    -.1184806    -.2476569
foreign           2.72132      .013019      17.2635     1.547907      3.23555
Total                 100      .478406          100      .478406            1
-----------------------------------------------------------------------------
Code
[top]

Approach 2: post results as vectors in e()

Instead of directly tabulating the matrix you can post the matrix columns as vectors in e() and then tabulate these vectors. This gives you some additional flexibility for formatting the columns. Here is an example (Stata 9 or newer is required):

. capture which ineqrbd      // check whether -ineqrbd- is installed

. if _rc ssc install ineqrbd // and get it if not

. sysuse auto, clear
(1978 Automobile Data)

. ineqrbd price trunk weight length foreign, noregression
 
Regression-based decomposition of inequality in  price
---------------------------------------------------------------------------
Decomp.  |     100*s_f        S_f     100*m_f/m      CV_f   CV_f/CV(total)
---------+-----------------------------------------------------------------
residual |     45.1031      0.2158      0.0000    1.79e+15    3.74e+15
trunk    |     -0.4687     -0.0022     -2.2943     -0.3109     -0.6499
weight   |     81.8711      0.3917    282.5215      0.2574      0.5380
length   |    -29.2268     -0.1398   -273.2854     -0.1185     -0.2477
foreign  |      2.7213      0.0130     17.2635      1.5479      3.2356
---------+-----------------------------------------------------------------
Total    |    100.0000      0.4784    100.0000      0.4784      1.0000
---------------------------------------------------------------------------
Note: proportionate contribution of composite var f to inequality of Total,
      s_f = rho_f*sd(f)/sd(Total). S_f = s_f*CV(Total).
      m_f = mean(f). sd(f) = std.dev. of f. CV_f = sd(f)/m_f.
      Total = price

. // Step 1: collect results from r(sf_Z#), r(mean_Z#), and r(cv_Z#)
. local xvars "`r(xvars)'"

. local nx : list sizeof xvars

. foreach s in sf mean cv {
  2.    tempname `s'
  3.    matrix ``s'' = J(`nx'+2, 1, .z)
  4.    matrix rownames ``s'' = residual `r(xvars)' Total
  5.    forv i = 0/`nx' {
  6.        matrix ``s''[`i'+1, 1] = `r(`s'_Z`i')'
  7.    }
  8. }

. matrix `sf'[rowsof(`sf'), 1]     = 1

. matrix `mean'[rowsof(`mean'), 1] = `r(mean_tot)'

. matrix `cv'[rowsof(`sf'), 1]     = `r(cv_tot)'

. // Step 2: build matrix that mirrors -ineqrbd-'s output
. matrix ineqrbd = ///
>    `sf' * 100 ,                    /// column 1: 100*s_f
>    `sf' * `r(cv_tot)' ,            /// column 2: S_f
>    `mean' / `r(mean_tot)' * 100,   /// column 3: 100*m_f/m
>    `cv',                           /// column 4: CV_f
>    `cv' / `r(cv_tot)'              //  column 5: CV_f/CV(total)

. matrix colnames ineqrbd = 100*s_f S_f 100*m_f/m CV_f CV_f/CV(total)

. // Step 3: post matrix columns in e()
. ereturn post

. tempname tmp

. local i 0

. foreach col in s_f100 S_f m_f100 CV_f CV_ftot {
  2.    local ++i
  3.    matrix `tmp' = ineqrbd[1...,`i']'
  4.    quietly estadd matrix `col' = `tmp'
  5. }

. ereturn list

matrices:
            e(CV_ftot) :  1 x 6
               e(CV_f) :  1 x 6
             e(m_f100) :  1 x 6
                e(S_f) :  1 x 6
             e(s_f100) :  1 x 6

. // Step 4: tabulate
. esttab, cell("s_f100 S_f m_f100 CV_f CV_ftot") noobs

-----------------------------------------------------------------------------
                      (1)                                                    
                                                                             
                   s_f100          S_f       m_f100         CV_f      CV_ftot
-----------------------------------------------------------------------------
residual         45.10308     .2157759     1.79e-14     1.79e+15     3.74e+15
trunk             -.46871    -.0022423    -2.294291    -.3109311    -.6499315
weight           81.87108     .3916762     282.5215     .2573949     .5380261
length          -29.22677    -.1398226    -273.2854    -.1184806    -.2476569
foreign           2.72132      .013019      17.2635     1.547907      3.23555
Total                 100      .478406          100      .478406            1
-----------------------------------------------------------------------------

. esttab, cell((S_f s_f100(fmt(1) par("" "%")))) noobs

--------------------------------------
                      (1)             
                                      
                      S_f       s_f100
--------------------------------------
residual         .2157759        45.1%
trunk           -.0022423        -0.5%
weight           .3916762        81.9%
length          -.1398226       -29.2%
foreign           .013019         2.7%
Total             .478406       100.0%
--------------------------------------
Code
[top]

Stacking models/bivariate effetcs

estout cannot stack models. A solution is to stack the models in advance and save the result in e(). Here is an example where the goal is to include a column containing the bivariate effects of the regressors:

. capt prog drop appendmodels

. *! version 1.0.0  14aug2007  Ben Jann
. program appendmodels, eclass
  1.     // using first equation of model
.     version 8
  2.     syntax namelist
  3.     tempname b V tmp
  4.     foreach name of local namelist {
  5.         qui est restore `name'
  6.         mat `tmp' = e(b)
  7.         local eq1: coleq `tmp'
  8.         gettoken eq1 : eq1
  9.         mat `tmp' = `tmp'[1,"`eq1':"]
 10.         local cons = colnumb(`tmp',"_cons")
 11.         if `cons'<. & `cons'>1 {
 12.             mat `tmp' = `tmp'[1,1..`cons'-1]
 13.         }
 14.         mat `b' = nullmat(`b') , `tmp'
 15.         mat `tmp' = e(V)
 16.         mat `tmp' = `tmp'["`eq1':","`eq1':"]
 17.         if `cons'<. & `cons'>1 {
 18.             mat `tmp' = `tmp'[1..`cons'-1,1..`cons'-1]
 19.         }
 20.         capt confirm matrix `V'
 21.         if _rc {
 22.             mat `V' = `tmp'
 23.         }
 24.         else {
 25.             mat `V' = ///
>             ( `V' , J(rowsof(`V'),colsof(`tmp'),0) ) \ ///
>             ( J(rowsof(`tmp'),colsof(`V'),0) , `tmp' )
 26.         }
 27.     }
 28.     local names: colfullnames `b'
 29.     mat coln `V' = `names'
 30.     mat rown `V' = `names'
 31.     eret post `b' `V'
 32.     eret local cmd "whatever"
 33. end

. sysuse auto, clear
(1978 Automobile Data)

. eststo b1: quietly regress price weight

. eststo b2: quietly regress price mpg

. eststo b3: quietly regress price foreign

. eststo bivar: appendmodels b1 b2 b3

. eststo multi: quietly regress price weight mpg foreign

. esttab b1 b2 b3 bivar, mtitles

----------------------------------------------------------------------------
                      (1)             (2)             (3)             (4)   
                       b1              b2              b3           bivar   
----------------------------------------------------------------------------
weight              2.044***                                        2.044***
                   (5.42)                                          (5.42)   

mpg                                -238.9***                       -238.9***
                                  (-4.50)                         (-4.50)   

foreign                                             312.3           312.3   
                                                   (0.41)          (0.41)   

_cons              -6.707         11253.1***       6072.4***                
                  (-0.01)          (9.61)         (14.76)                   
----------------------------------------------------------------------------
N                      74              74              74                   
----------------------------------------------------------------------------
t statistics in parentheses
* p<0.05, ** p<0.01, *** p<0.001

. esttab multi bivar, mtitles

--------------------------------------------
                      (1)             (2)   
                    multi           bivar   
--------------------------------------------
weight              3.465***        2.044***
                   (5.49)          (5.42)   

mpg                 21.85          -238.9***
                   (0.29)         (-4.50)   

foreign            3673.1***        312.3   
                   (5.37)          (0.41)   

_cons             -5853.7                   
                  (-1.73)                   
--------------------------------------------
N                      74                   
--------------------------------------------
t statistics in parentheses
* p<0.05, ** p<0.01, *** p<0.001

. eststo clear
Code
[top]

Group sizes for factor variables

Assume you are including a categorical variable in a regression model and want to report the group sizes. You could proceed as follows:

. sysuse auto, clear
(1978 Automobile Data)

. reg price weight mpg i.rep

      Source |       SS           df       MS      Number of obs   =        69
-------------+----------------------------------   F(6, 62)        =      6.03
       Model |   212481723         6  35413620.6   Prob > F        =    0.0001
    Residual |   364315236        62  5876052.19   R-squared       =    0.3684
-------------+----------------------------------   Adj R-squared   =    0.3073
       Total |   576796959        68  8482308.22   Root MSE        =    2424.1

------------------------------------------------------------------------------
       price |      Coef.   Std. Err.      t    P>|t|     [95% Conf. Interval]
-------------+----------------------------------------------------------------
      weight |   2.093066    .636901     3.29   0.002     .8199193    3.366213
         mpg |   -63.0971   87.45276    -0.72   0.473    -237.9127    111.7185
             |
       rep78 |
          2  |   753.7024   1919.763     0.39   0.696    -3083.849    4591.254
          3  |   1349.361   1772.706     0.76   0.449    -2194.228     4892.95
          4  |    2030.47    1810.09     1.12   0.266    -1587.848    5648.788
          5  |    3376.91    1900.17     1.78   0.080    -421.4749    7175.296
             |
       _cons |  -598.9665   3960.904    -0.15   0.880    -8516.701    7318.768
------------------------------------------------------------------------------

. capt matrix drop nobs

. local collab

. levelsof rep if e(sample)
1 2 3 4 5

. foreach cat in `r(levels)' {
  2.     quietly count if `cat'.rep78==1 & e(sample)
  3.     matrix nobs = nullmat(nobs), r(N)
  4.     local collab `collab' `cat'.rep78
  5. }

. matrix colname nobs = `collab'

. estadd matrix nobs

added matrix:
               e(nobs) :  1 x 5

. esttab, cells("b(fmt(a3)) t(fmt(2)) nobs") nogap 

---------------------------------------------------
                      (1)                          
                    price                          
                        b            t         nobs
---------------------------------------------------
weight              2.093         3.29             
mpg                -63.10        -0.72             
1.rep78                 0            .            2
2.rep78             753.7         0.39            8
3.rep78            1349.4         0.76           30
4.rep78            2030.5         1.12           18
5.rep78            3376.9         1.78           11
_cons              -599.0        -0.15             
---------------------------------------------------
N                      69                          
---------------------------------------------------
Code

Here is the same example using the the xi command:

. sysuse auto, clear
(1978 Automobile Data)

. xi: reg price weight mpg i.rep
i.rep78           _Irep78_1-5         (naturally coded; _Irep78_1 omitted)

      Source |       SS           df       MS      Number of obs   =        69
-------------+----------------------------------   F(6, 62)        =      6.03
       Model |   212481723         6  35413620.6   Prob > F        =    0.0001
    Residual |   364315236        62  5876052.19   R-squared       =    0.3684
-------------+----------------------------------   Adj R-squared   =    0.3073
       Total |   576796959        68  8482308.22   Root MSE        =    2424.1

------------------------------------------------------------------------------
       price |      Coef.   Std. Err.      t    P>|t|     [95% Conf. Interval]
-------------+----------------------------------------------------------------
      weight |   2.093066    .636901     3.29   0.002     .8199193    3.366213
         mpg |   -63.0971   87.45276    -0.72   0.473    -237.9127    111.7185
   _Irep78_2 |   753.7024   1919.763     0.39   0.696    -3083.849    4591.254
   _Irep78_3 |   1349.361   1772.706     0.76   0.449    -2194.228     4892.95
   _Irep78_4 |    2030.47    1810.09     1.12   0.266    -1587.848    5648.788
   _Irep78_5 |    3376.91    1900.17     1.78   0.080    -421.4749    7175.296
       _cons |  -598.9665   3960.904    -0.15   0.880    -8516.701    7318.768
------------------------------------------------------------------------------

. local collab

. capt matrix drop nobs

. foreach cat of varlist _Irep* {
  2.     quietly count if `cat'==1 & e(sample)
  3.     matrix nobs = nullmat(nobs), r(N)
  4.     local collab `collab' `cat'
  5. }

. matrix colname nobs = `collab'

. estadd matrix nobs

added matrix:
               e(nobs) :  1 x 4

. esttab, cells("b(fmt(a3)) t(fmt(2)) nobs") nogap

---------------------------------------------------
                      (1)                          
                    price                          
                        b            t         nobs
---------------------------------------------------
weight              2.093         3.29             
mpg                -63.10        -0.72             
_Irep78_2           753.7         0.39            8
_Irep78_3          1349.4         0.76           30
_Irep78_4          2030.5         1.12           18
_Irep78_5          3376.9         1.78           11
_cons              -599.0        -0.15             
---------------------------------------------------
N                      69                          
---------------------------------------------------
Code
[top]

Results from stci

[This example is outdated; see the estpost example on Survival time CIs (stci).]

The stci command to compute confidence intervals for survival time estimates returns its results in r(), or not at all if used with the by() option. The following example therefore provides a wrapper for stci that collects the results and posts them in e(), so that they can be tabulated using estout or esttab:

. capt prog drop e_stci

. *! version 1.0.0  16sep2008  Ben Jann
. prog e_stci, eclass
  1.     version 9.2
  2.     syntax [if] [in] [ , by(varname) Median Rmean Emean p(str) * ]
  3.     local stat "p50"
  4.     if `"`p'"'!=""          local stat `"p`p'"'
  5.     else if "`rmean'"!=""   local stat "rmean"
  6.     else if "`emean'"!=""   local stat "emean"
  7.     tempname b V N_sub lb ub
  8.     marksample touse
  9.     if "`by'"!="" {
 10.         markout `touse' `by', strok
 11.         qui levelsof `by' if `touse', local(levels)
 12.     }
 13.     local levels `"`levels' "total""'
 14.     gettoken l rest : levels, quotes
 15.     while (`"`l'"'!="") {
 16.         if `"`rest'"'=="" local lcond
 17.         else              local lcond `" & `by'==`l'"'
 18.         qui stci if `touse'`lcond', `median' `rmean' `emean' `p' `options'
 19.         mat `b' = nullmat(`b'), r(`stat')
 20.         mat `V' = nullmat(`V'), r(se)^2
 21.         mat `N_sub' = nullmat(`N_sub'), r(N_sub)
 22.         mat `lb' = nullmat(`lb'), r(lb)
 23.         mat `ub' = nullmat(`ub'), r(ub)
 24.         gettoken l rest : rest
 25.     }
 26.     foreach m in b V N_sub lb ub {
 27.         mat coln ``m'' = `levels'
 28.     }
 29.     if matmissing(`V') {
 30.         mat `V' = `b'' * `b' * 0  // set V to zero
 31.     }
 32.     else {
 33.         mat `V' = diag(`V')
 34.     }
 35.     eret post `b' `V'
 36.     eret matrix N_sub = `N_sub'
 37.     eret matrix lb = `lb'
 38.     eret matrix ub = `ub'
 39.     eret local cmd "e_stci"
 40. end

. webuse page2, clear

. stci, by(group)

         failure _d:  dead
   analysis time _t:  time

             |    no. of 
group        |  subjects         50%     Std. Err.     [95% Conf. Interval]
-------------+-------------------------------------------------------------
           1 |        19         216      7.661029          190        234
           2 |        21         233      3.081611          232        280
-------------+-------------------------------------------------------------
       total |        40         232      2.562933          213        239

. e_stci, by(group)

. ereturn list

macros:
                e(cmd) : "e_stci"
         e(properties) : "b V"

matrices:
                  e(b) :  1 x 3
                  e(V) :  3 x 3
                 e(ub) :  1 x 3
                 e(lb) :  1 x 3
              e(N_sub) :  1 x 3

. estout, cell("N_sub b(label(50%)) se lb ub")

-----------------------------------------------------------------------------
                        .                                                    
                    N_sub          50%           se           lb           ub
-----------------------------------------------------------------------------
1                      19          216     7.661029          190          234
2                      21          233     3.081611          232          280
total                  40          232     2.562933          213          239
-----------------------------------------------------------------------------
Code