Frequency Table with Esttab - stata

I'm interested in outputting the transpose of the tabulate command using Stata:
sysuse auto, clear
eststo: estpost tab foreign
esttab, cells(b)
Such that the output would be
--------------------------------------------------
Domestic Foreign Total
--------------------------------------------------
Domestic 52. 22. 74
--------------------------------------------------
I can do something similar with the following:
sysuse auto, clear
est clear
tab foreign, gen(newp_`i')
eststo : estpost tabstat newp_1 newp_2 , stat(sum ) column(variables)
drop newp*
esttab, cells("newp_1 newp_2") ///
compress unstack ///
nonumbers nodepvars noobs ///
mtitles("Domestic" "Foreign")
...
------------------------------
Domestic
newp_1 newp_2
------------------------------
sum 52 22
------------------------------
But I run into issues when I try to add counts of other variables (Ideally I'd like est2 to be appended vertically instead of horizontally)
sysuse auto, clear
est clear
tab foreign, gen(newp_`i')
eststo : estpost tabstat newp_1 newp_2 , stat(sum ) column(variables)
drop newp*
esttab, cells("newp_1 newp_2") ///
compress unstack ///
nonumbers nodepvars noobs ///
mtitles("Domestic" "Foreign")
g example = (mpg >=22)
tab example, gen(newp_`i')
eststo : estpost tabstat newp_1 newp_2 , stat(sum ) column(variables)
esttab, cells("newp_1 newp_2") unstack ///
compress ///
nonumbers nodepvars noobs ///
mtitles("Domestic" "Foreign")
...
--------------------------------------------------
Domestic Foreign
newp_1 newp_2 newp_1 newp_2
--------------------------------------------------
sum 52 22 43 31
--------------------------------------------------
My desired output is:
---------------------------------
newp_1 newp_2
---------------------------------
sum (foreign) 52 22
sum (price) 43 31
---------------------------------

The following seems to work:
sysuse auto, clear
est clear
rename foreign binary1
g binary2 = (mpg >=22)
unab lst : binary*
foreach i in `lst'{
tab `i', gen(test_`v')
eststo: estpost tabstat test_*, statistics(sum) columns(statistics)
drop test_*
}
esttab , ///
replace cell(sum ) ///
compress ///
nonumbers rename("test_1" "Yes" "test_2" "No") ///
mtitles("Binary1" "Binary2")
matrix transp = r(coefs)'
esttab matrix(transp), compress eqlabels(,merge)

Related

Export tabulation in Excel

Consider the following toy example:
sysuse auto, clear
tab foreign, sum(price)
| Summary of Price
Car type | Mean Std. Dev. Freq.
------------+------------------------------------
Domestic | 6,072.423 3,097.104 52
Foreign | 6,384.682 2,621.915 22
------------+------------------------------------
Total | 6,165.257 2,949.496 74
How can I save the results in an Excel file?
Using the community-contributed command esttab, the following works for me:
sysuse auto, clear
egen m_total = mean(price)
egen s_total = sd(price)
scalar mtotal = m_total
scalar stotal = s_total
scalar N = _N
collapse (mean) Mean=price (sd) StdDev=price (count) Freq = price, by(foreign)
set obs 3
replace Mean = mtotal in 3
replace StdDev = stotal in 3
replace Freq = N in 3
mkmat Mean StdDev Freq, matrix(A)
esttab matrix(A) using myfilename.xls, varlabels(r1 Domestic r2 Foreign r3 Total) ///
title(" Summary of Price") mlabels(none)
Summary of Price
---------------------------------------------------
Mean StdDev Freq
---------------------------------------------------
Domestic 6072.423 3097.104 52
Foreign 6384.682 2621.915 22
Total 6165.257 2949.496 74
---------------------------------------------------

Combining output from linear and non-linear regressions in esttab

I display the results of two regressions using the community-contributed command esttab:
sysuse auto, clear
quietly reg price weight
est store ols
quietly nl (price = {b0} + {b1} * weight)
est store nls
esttab *
--------------------------------------------
(1) (2)
price price
--------------------------------------------
main
weight 2.044***
(5.42)
_cons -6.707 -6.707
(-0.01) (-0.01)
--------------------------------------------
b1
_cons 2.044***
(5.42)
--------------------------------------------
N 74 74
--------------------------------------------
t statistics in parentheses
* p<0.05, ** p<0.01, *** p<0.001
How can I make the b1 coefficient from the nl command to appear in the weight row?
The easiest way of doing this is the following:
sysuse auto, clear
estimates clear
regress price weight
estimates store ols
nl (price = {b0} + {b1} * weight)
matrix b = e(b)
matrix V = e(V)
matrix coleq b = " "
matrix coleq V = " "
matrix colnames b = _cons weight
matrix colnames V = _cons weight
erepost b = b V = V, rename
estimates store nls
Results:
esttab ols nls
--------------------------------------------
(1) (2)
price price
--------------------------------------------
weight 2.044*** 2.044***
(5.42) (5.42)
_cons -6.707 -6.707
(-0.01) (-0.01)
--------------------------------------------
N 74 74
--------------------------------------------
t statistics in parentheses
* p<0.05, ** p<0.01, *** p<0.001
Note that erepost is a community-contributed command, which you can download from SSC:
ssc install erepost

Create table with variable means and differences using esttab

I want to generate a table in Stata that contains means, differences and t-values for 4 different groups.
In particular, say you have 2x2 study design and want to display the mean and standard deviation of the outcome variable and add a further column that tests for the difference across treatment one and a further row that contains the difference and t-value across treatment two.
I have the following code:
clear
sysuse auto
gen large_trunk = (trunk > 14)
gen price_large_trunk = price if large_trunk == 1
gen price_small_trunk = price if large_trunk == 0
eststo price_domestic: qui estpost sum price_large_trunk price_small_trunk if foreign == 0
eststo price_foreign: qui estpost sum price_large_trunk price_small_trunk if foreign == 1
eststo diff: qui estpost ttest price_large_trunk price_small_trunk, by(foreign)
eststo diff2: qui estpost ttest price if foreign == 0, by(large_trunk)
eststo diff3: qui estpost ttest price if foreign == 1, by(large_trunk)
esttab price_domestic price_foreign diff diff2 diff3, ///
cells("mean(pattern(1 1 0) fmt(2)) b(star pattern(0 0 1) fmt(2))" "sd(pattern(1 1 0) par) t(pattern(0 0 1) par)") ///
mtitle("Domestic" "Foreign" "Difference") ///
nonumbers noobs ///
coeflabels(price "Difference") ///
notes
The output is:
----------------------------------------------------------------------------------------------------------------
Domestic Foreign Difference diff2 diff3
mean/sd mean/sd b/t mean/sd b/t mean/sd b/t
----------------------------------------------------------------------------------------------------------------
price_larg~k 6900.13 6186.00 714.13
(3164.76) (2186.93) (0.48)
price_smal~k 4850.57 6443.12 -1592.55
(2608.98) (2794.83) (-1.81)
Difference -2049.56* 257.12
(-2.45) (0.19)
----------------------------------------------------------------------------------------------------------------
As you can see this is a 7x3 table. Ideally I would want to have the elements in the last row in columns one and two and discard all columns after column three.
On a related note, I also wonder if I can suppress the summary statistics in the table header (I mean the mean/sd and b/t under the treatment names).
You need to modify your code as follows:
sysuse auto, clear
est clear
gen large_trunk = (trunk > 14)
gen price_large_trunk = price if large_trunk == 1
gen price_small_trunk = price if large_trunk == 0
qui estpost sum price_large_trunk price_small_trunk if foreign == 0
qui ttest price if foreign == 0, by(large_trunk)
estadd local diff2 `= round(r(mu_1) - r(mu_2), .01)'
estadd local tdiff2 (`= round(`r(t)', .01)')
eststo price_domestic
qui estpost sum price_large_trunk price_small_trunk if foreign == 1
qui ttest price if foreign == 1, by(large_trunk)
estadd local diff2 `= round(r(mu_1) - r(mu_2), .01)'
estadd local tdiff2 (`= round(`r(t)', .01)')
eststo price_foreign
eststo diff1: qui estpost ttest price_large_trunk price_small_trunk, by(foreign)
esttab price_domestic price_foreign diff1, ///
stats(diff2 tdiff2, label("Difference" " ") ) ///
cells("mean(pattern(1 1 0) fmt(2)) b(star pattern(0 0 1) fmt(2))" "sd(pattern(1 1 0) par) t(pattern(0 0 1) par)") ///
mtitle("Domestic" "Foreign" "Difference") collabels(none) ///
nonumbers noobs ///
coeflabels(price "Difference") ///
notes
Result:
------------------------------------------------------
Domestic Foreign Difference
------------------------------------------------------
price_larg~k 6900.13 6186.00 714.13
(3164.76) (2186.93) (0.48)
price_smal~k 4850.57 6443.12 -1592.55
(2608.98) (2794.83) (-1.81)
------------------------------------------------------
Difference -2049.56 257.12
(-2.45) (.19)
------------------------------------------------------
Or perhaps:
esttab price_domestic price_foreign diff1, ///
stats(diff2 tdiff2, label("Difference" " ") ) ///
cells("mean(pattern(1 1 0) fmt(2)) b(star pattern(0 0 1) fmt(2))" "sd(pattern(1 1 0) par) t(pattern(0 0 1) par)") ///
mtitle("Domestic" "Foreign" "Difference") collabels(none) ///
nonumbers noobs ///
coeflabels(price "Difference") ///
notes gaps prefoot(" ")
------------------------------------------------------
Domestic Foreign Difference
------------------------------------------------------
price_larg~k 6900.13 6186.00 714.13
(3164.76) (2186.93) (0.48)
price_smal~k 4850.57 6443.12 -1592.55
(2608.98) (2794.83) (-1.81)
Difference -2049.56 257.12
(-2.45) (.19)
------------------------------------------------------
Or even:
esttab price_domestic price_foreign diff1, ///
stats(diff2 tdiff2, label("Difference" " ") ) ///
cells("mean(pattern(1 1 0) fmt(2)) b(star pattern(0 0 1) fmt(2))" "sd(pattern(1 1 0) par) t(pattern(0 0 1) par)") ///
mtitle("Domestic" "Foreign" "Difference") collabels(none) ///
nonumbers noobs ///
coeflabels(price "Difference") ///
notes gaps plain
Domestic Foreign Difference
price_larg~k 6900.13 6186.00 714.13
(3164.76) (2186.93) (0.48)
price_smal~k 4850.57 6443.12 -1592.55
(2608.98) (2794.83) (-1.81)
Difference -2049.56 257.12
(-2.45) (.19)

Replace/delete line in tex output of esttab

I am trying to get rid of a line with the statistics label/name "mean" in the output of the Stata code:
**********************************************************
**** Produce table with mean values of hhi_r, jsi_r, top4_r, hhi, jsi in
decending order of hhi_r
** sort output by mean hhi_r
drop mean group
egen mean = mean(hhi_r), by(name)
egen group = group(mean name)
replace group = -group
labmask group, values(name)
label var group "`: var label name'"
** done sorting
label var hhi_r "rank(\$HHI\$)"
label var jsi_r "rank(\$C1_I\$)"
label var top4_r "rank(\$T4\$)"
label var hhi "\$HHI\$"
label var jsi "\$C1_I\$"
eststo clear
eststo t1: estpost tabstat jsi_r, by(group) statistics(mean) columns(statistics) listwise nototal
eststo t2: estpost tabstat top4_r, by(group) statistics(mean) columns(statistics) listwise nototal
eststo t3: estpost tabstat hhi, by(group) statistics(mean) columns(statistics) listwise nototal
eststo t4: estpost tabstat jsi, by(group) statistics(mean) columns(statistics) listwise nototal
eststo t0: estpost tabstat hhi_r, by(group) statistics(count mean sd p10 p25 p50 p75 p90) columns(statistics) listwise nototal
esttab t0 t1 t2 t3 t4 using "$Tables/hhi_r.tex", replace style(tex) type ///
cells("mean(fmt(%15.0fc))") alignment(r) substitute(\_ _) ///
noobs nonumber varlabels(`e(labels)') varwidth(20) mlabels("rank(HHI)" "rank(C1)" "rank(T4)" "HHI" "C1")
The output is a TeX file that includes as the second line the label/name "mean" of the statistics:
{
\def\sym#1{\ifmmode^{#1}\else\(^{#1}\)\fi}
\begin{tabular}{l*{5}{r}}
\hline\hline
& rank(HHI)& rank(C1)& rank(T4)& HHI& C1\\
& mean& mean& mean& mean& mean\\
\hline
624: Social Assistance& 2,332& 4& 4& 10,000& 1\\
425: Wholesale Electronic Markets and Agents and Broker& 2,332& & & 10,000& \\
113: Forestry and Logging& 2,332& & & 10,000& \\
115: Support Activities for Agriculture and Forestry& 2,326& & & 9,477& \\
314: Textile Product Mills& 2,324& & & 7,501& \\
112: Animal Production and Aquaculture& 2,321& & & 6,968& \\
492: Couriers and Messengers& 2,318& 1,225& & 6,821& 484\\
811: Repair and Maintenance& 2,316& 2& 2& 5,976& 1\\
\hline\hline
\end{tabular}
}
How can I suppress this line or replace the names/labels with the strings in the mlabels() option of the community-contributed command esttab?
Using Stata's toy auto dataset as an example, the following works for me:
sysuse auto, clear
eststo clear
eststo t1: estpost tabstat price, by(foreign) statistics(mean) columns(statistics) listwise nototal
eststo t2: estpost tabstat mpg, by(foreign) statistics(mean) columns(statistics) listwise nototal
eststo t3: estpost tabstat weight, by(foreign) statistics(mean) columns(statistics) listwise nototal
eststo t4: estpost tabstat length, by(foreign) statistics(mean) columns(statistics) listwise nototal
eststo t0: estpost tabstat mpg, by(foreign) statistics(count mean sd p10 p25 p50 p75 p90) columns(statistics) listwise nototal
esttab t0 t1 t2 t3 t4 using "table.tex", replace style(tex) ///
type cells(`"mean(fmt(%15.0fc) label(" "))"') alignment(r) substitute(\_ _) ///
noobs nonumber varlabels(`e(labels)') varwidth(20) ///
mlabels("rank(HHI)" "rank(C1)" "rank(T4)" "HHI" "C1")
type table.tex
{
\def\sym#1{\ifmmode^{#1}\else\(^{#1}\)\fi}
\begin{tabular}{l*{5}{r}}
\hline\hline
& rank(HHI)& rank(C1)& rank(T4)& HHI& C1\\
& & & & & \\
\hline
Domestic & 20& 6,072& 20& 3,317& 196\\
Foreign & 25& 6,385& 25& 2,316& 169\\
\hline\hline
\end{tabular}
}
You basically substitute each statistic name with a space by specifying the label(" ") suboption in cells(mean()).
Alternatively, to eliminate the line completely use the option collabels(none):
esttab t0 t1 t2 t3 t4 using "table.tex", replace style(tex) ///
type cells(`"mean(fmt(%15.0fc))"') alignment(r) substitute(\_ _) ///
noobs nonumber varlabels(`e(labels)') varwidth(20) ///
mlabels("rank(HHI)" "rank(C1)" "rank(T4)" "HHI" "C1") collabels(none)
type table.tex
{
\def\sym#1{\ifmmode^{#1}\else\(^{#1}\)\fi}
\begin{tabular}{l*{5}{r}}
\hline\hline
& rank(HHI)& rank(C1)& rank(T4)& HHI& C1\\
\hline
Domestic & 20& 6,072& 20& 3,317& 196\\
Foreign & 25& 6,385& 25& 2,316& 169\\
\hline\hline
\end{tabular}
}

Add marginal effect t-statistics to an estout table

I would like to add marginal effect t-statistics to an estout table (ssc install estout).
I can add marginal effect coefficients and standard errors with estadd margins.
However, margins does not add t-statistics.
I thought that I could add a t-statistic with estadd matrix but this code fails to calculate margins_t:
webuse grunfeld
eststo clear
regress mvalue c.kstock##c.invest
eststo
estadd margins, dydx(kstock)
estadd matrix margins_t = margins_b :/ margins_se
I want to report marginal effects for only kstock (i.e., only one of the interaction variables):
esttab, cells("b margins_b" "t(par) margins_se(par)")
--------------------------------------
(1)
mvalue
b/t margins_b/~e
--------------------------------------
kstock -.0229636 -.2073908
(-.0947377) (.2213873)
invest 6.672997
(19.13787)
c.kstock#c~t -.0012636
(-4.351608)
_cons 219.3425
(2.903506)
--------------------------------------
N 200
--------------------------------------
The standard errors version works but I would prefer t-statistics.
The following works for me:
webuse grunfeld
eststo clear
eststo m1: regress mvalue c.kstock##c.invest
eststo m2: margins, dydx(kstock) post
esttab m1 m2 using output, replace
type output.txt
--------------------------------------------
(1) (2)
mvalue
--------------------------------------------
kstock -0.0230 -0.207
(-0.09) (-0.94)
invest 6.673***
(19.14)
c.kstock#c~t -0.00126***
(-4.35)
_cons 219.3**
(2.90)
--------------------------------------------
N 200 200
--------------------------------------------
t statistics in parentheses
* p<0.05, ** p<0.01, *** p<0.001
A revision addressing the concerns in OP's comment:
eststo clear
eststo m1: regress mvalue c.kstock##c.invest
estadd local Obs = e(N)
eststo m2: margins, dydx(kstock) post
esttab m1 m2, s(Obs) mtitles("(1)" "") nonumbers noobs
--------------------------------------------
(1)
--------------------------------------------
kstock -0.0230 -0.207
(-0.09) (-0.94)
invest 6.673***
(19.14)
c.kstock#c~t -0.00126***
(-4.35)
_cons 219.3**
(2.90)
--------------------------------------------
Obs 200
--------------------------------------------
t statistics in parentheses
* p<0.05, ** p<0.01, *** p<0.001
There are (at least) two problems with the code in my question.
:/ is elementwise division in Mata. Use matewd for elementwise division in Stata. matewd is from a Stata technical bulletin, so use findit matewd.
Elementwise division would not retain column names, which estout uses to align coefficient estimates and other statistics properly.
The code below solves the original question but requires a handful of extra steps. It may be easier to manually modify the table layout than taking this handful of additional steps.
webuse grunfeld
eststo clear
regress mvalue c.kstock##c.invest
eststo
estadd margins, dydx(kstock)
matrix margins_b = e(margins_b)
matrix margins_se = e(margins_se)
matewd margins_b margins_se margins_t
local colnames : colnames margins_b
matrix colnames margins_t = "`colnames'"
estadd matrix margins_t
esttab, cells("b margins_b" "t(par) margins_t(par)")
// --------------------------------------
// (1)
// mvalue
// b/t margins_b/~t
// --------------------------------------
// kstock -.0229636 -.2073908
// (-.0947377) (-.9367782)
// invest 6.672997
// (19.13787)
// c.kstock#c~t -.0012636
// (-4.351608)
// _cons 219.3425
// (2.903506)
// --------------------------------------
// N 200
// --------------------------------------
esttab, cells(b t(par) margins_b margins_t(par))
// -------------------------
// (1)
// mvalue
// b/t/margin~t
// -------------------------
// kstock -.0229636
// (-.0947377)
// -.2073908
// (-.9367782)
// invest 6.672997
// (19.13787)
// c.kstock#c~t -.0012636
// (-4.351608)
// _cons 219.3425
// (2.903506)
// -------------------------
// N 200
// -------------------------