Add marginal effect t-statistics to an estout table - stata

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
// -------------------------

Related

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

How can I add a fixed effect model label to an estout table?

Below you can find my code:
#delimit;
local fixed_effect "Yes";
estout pre_post using output.xls, cells(b(star fmt(4) keep(post
`ctrlVars')) t(par fmt(2) keep(post `ctrlVars')))
legend starlevels( * 0.10 ** 0.05 *** 0.010) stats(`fixed_effect' r2 N
labels("Industry fixed effects" "Adjusted R-squared")) varlabels(_cons
Constant) append;
This produces the following error message:
( invalid name
"Industry fixed effects invalid name
"Adjusted R-squared invalid name
) invalid name
r(7);
What is wrong?
EDIT:
Sorry for not being clear enough. This is what I would like to have:
----------------------------
(1)
Industry FEs
b/t
----------------------------
mpg -174.3133*
(-1.99)
headroom -520.2934
(-1.23)
length 31.3659
(1.30)
Constant 5540.3487
(0.94)
----------------------------
Industry FE Yes
Adjusted R~d 0.2454
N 74
----------------------------
* p<0.10, ** p<0.05, *** p<0.010
I can reproduce your problem using Stata's toy dataset auto as follows:
sysuse auto, clear
regress price mpg headroom length
#delimit;
esttab ., cells(b(star fmt(4)) t(par fmt(2)))
legend starlevels( * 0.10 ** 0.05 *** 0.010) stats(r2 N
label("Industry fixed effects" "Adjusted R-squared")) varlabels(_cons
Constant);
( invalid name
"Industry fixed effects invalid name
"Adjusted R-squared invalid name
) invalid name
r(7);
This error happens because you are using the options of the community-contributed command estout incorrectly: labels() is a sub-option of stats() and thus it has to be separated using a comma. In addition, you need the standalone option mlabels() to specify a custom model name:
esttab ., cells(b(star fmt(4)) t(par fmt(2))) legend ///
starlevels(* 0.10 ** 0.05 *** 0.010) stats(r2 N, labels("Adjusted R-squared")) ///
mlabels("Industry FEs") varlabels(_cons Constant)
----------------------------
(1)
Industry FEs
b/t
----------------------------
mpg -174.3133*
(-1.99)
headroom -520.2934
(-1.23)
length 31.3659
(1.30)
Constant 5540.3487
(0.94)
----------------------------
Adjusted R~d 0.2454
N 74.0000
----------------------------
* p<0.10, ** p<0.05, *** p<0.010
Note that delimit also appears to cause some issues.
EDIT:
You need to use estadd for that:
sysuse auto, clear
regress price mpg headroom length
estadd local fe Yes
esttab ., cells(b(star fmt(4)) t(par fmt(2))) legend ///
starlevels(* 0.10 ** 0.05 *** 0.010) stats(fe r2 N, ///
labels("Industry FE" "Adjusted R-squared")) ///
mlabels("Industry FEs") varlabels(_cons Constant)
----------------------------
(1)
Industry FEs
b/t
----------------------------
mpg -174.3133*
(-1.99)
headroom -520.2934
(-1.23)
length 31.3659
(1.30)
Constant 5540.3487
(0.94)
----------------------------
Industry FE Yes
Adjusted R~d 0.2454
N 74.0000
----------------------------
* p<0.10, ** p<0.05, *** p<0.010

How can I stack equations using estout?

I am creating a summary statistics table using the community-contributed command estout.
The code looks like this:
sysuse auto, clear
eststo clear
eststo: estpost ttest price mpg weight headroom trunk if rep78 ==3, by(foreign)
eststo: estpost ttest price mpg weight headroom trunk if rep78 ==4, by(foreign)
estout, cells("mu_1 mu_2 b(star)")
The result looks as follows:
--------------------------------------------------------------------------------------------
est1 est2
mu_1 mu_2 b mu_1 mu_2 b
--------------------------------------------------------------------------------------------
price 6607.074 4828.667 1778.407 5881.556 6261.444 -379.8889
mpg 19 23.33333 -4.333333 18.44444 24.88889 -6.444444**
weight 3442.222 2010 1432.222*** 3532.222 2207.778 1324.444***
headroom 3.222222 2.666667 .5555556 3.444444 2.5 .9444444*
trunk 15.59259 12.33333 3.259259 16.66667 10.33333 6.333333**
--------------------------------------------------------------------------------------------
I would like to know how I could stack est1 and est2 on top of each other.
The command estout cannot automatically stack results from stored estimates. Consequently, the use of eststo is redundant. In this case, the easiest way to obtain the desired output is to simply create two matrices with the results and stack one on top of the other.
For example:
sysuse auto, clear
matrix A = J(5, 3, .)
local i 0
foreach var of varlist price mpg weight headroom trunk {
local ++i
ttest `var' if rep78 == 3, by(foreign)
matrix A[`i', 1] = r(mu_1)
matrix A[`i', 2] = r(mu_2)
matrix A[`i', 3] = r(mu_1) - r(mu_2)
local matnamesA `matnamesA' "rep78==3:`var'"
}
matrix rownames A = `matnamesA'
matrix B = J(5, 3, .)
local i 0
foreach var of varlist price mpg weight headroom trunk {
local ++i
ttest `var' if rep78 == 4, by(foreign)
matrix B[`i', 1] = r(mu_1)
matrix B[`i', 2] = r(mu_2)
matrix B[`i', 3] = r(mu_1) - r(mu_2)
local matnamesB `matnamesB' "rep78==4:`var'"
}
matrix rownames B = `matnamesB'
matrix C = A \ B
esttab matrix(C), nomtitles collabels("mu_1" "mu_2" "diff")
---------------------------------------------------
mu_1 mu_2 diff
---------------------------------------------------
rep78==3
price 6607.074 4828.667 1778.407
mpg 19 23.33333 -4.333333
weight 3442.222 2010 1432.222
headroom 3.222222 2.666667 .5555556
trunk 15.59259 12.33333 3.259259
---------------------------------------------------
rep78==4
price 5881.556 6261.444 -379.8889
mpg 18.44444 24.88889 -6.444444
weight 3532.222 2207.778 1324.444
headroom 3.444444 2.5 .9444444
trunk 16.66667 10.33333 6.333333
---------------------------------------------------

Write a Stata eclass program that only returns a vector of p-values

Edit: After one day I cross-posted this Statalist.
I want to write my own eclass program to work with eststo and esttab from SSC's esttab.
I want to write a wrapper for ranksum so that I can get the p-values and add them to a table alongside the p-values from t-tests. From the ereturn help file it seems like I need to return a b matrix to comply with eclass, but I can't figure out how.
I commented the bad calls below. Making the table with means and t-tests is no problem (i.e., first 3 columns). But my Wilcoxon3 command gives an error. I have tried with and without returning b, but I can't figure out the error, which is invalid syntax.
I am OK with any solution that puts the ranksum p-values into an e() container.
capture program drop Wilcoxon3
program define Wilcoxon3, eclass
version 13
syntax varlist [if] [in], by(varname)
marksample touse
local names
foreach v of varlist `varlist' {
ranksum `v' if `touse', by(`by')
matrix b = nullmat(b), 1
matrix p = nullmat(p), 2*normprob(-abs(r(z)))
local names `names' "`v'"
}
matrix colnames p = `names'
// store results
ereturn post b
ereturn matrix p
end
sysuse auto, clear
eststo clear
/* store means and t-tests */
estpost summarize price weight if !foreign
eststo
estpost summarize price weight if foreign
eststo
estpost ttest price weight, by(foreign)
eststo
/* /1* try to store rank-sum test *1/ */
/* Wilcoxon3 price weight, by(foreign) */
/* eststo */
/* table of means and t-tests */
esttab, cells("mean(pattern(1 0 0) fmt(3) label(!Foreign)) mean(pattern(0 1 0) fmt(3) label(Foreign)) p(star pattern(0 0 1) fmt(3) label(p))")
/* /1* try table of means, t-tests, and rank-sum tests *1/ */
/* esttab, cells("mean(pattern(1 0 0 0) fmt(3) label(!Foreign)) mean(pattern(0 1 0 0) fmt(3) label(Foreign)) p(star pattern(0 0 1 0) fmt(3) label(p)) p(star pattern(0 0 0 1) fmt(3) label(p))") */
I received an answer on Statalist here.
This was a case of RTFM. The ereturn post syntax doesn't require rename and equal sign, but ereturn matrix does. This is clear if you focus on the syntax example provided at the top of the ereturn help page. The = is optional, but a new name is not.
The correct code is ereturn matrix p = p.

Exporting results from regressions in Excel

I want to store results from ordinary least squares (OLS) regressions in Stata within a double loop.
Here is the structure of my code:
foreach i2 of numlist 1 2 3{
foreach i3 of numlist 1 2 3 4{
quiet: eststo: reg dep covariates, robust
}
}
The end goal is to have a table in Excel composed by twelve rows (one for each model) and seven columns (number of observations, estimated constant, five estimated coefficients).
Any suggestion on how can I do this?
Such a table can be created simply by using the community-contributed command esttab:
sysuse auto, clear
eststo clear
eststo m1: quietly regress price weight
eststo m2: quietly regress price weight mpg
quietly esttab
matrix A = r(coefs)'
matrix C = r(stats)'
tokenize "`: rownames A'"
forvalues i = 1 / `=rowsof(A)' {
if strmatch("``i''", "*b*") matrix B = nullmat(B) \ A[`i', 1...]
}
matrix C = B , C
matrix rownames C = "Model 1" "Model 2"
Result:
esttab matrix(C) using table.csv, eqlabels(none) mlabels(none) varlabels("Model 1" "Model 2")
----------------------------------------------------------------
weight mpg _cons N
----------------------------------------------------------------
Model 1 2.044063 -6.707353 74
Model 2 1.746559 -49.51222 1946.069 74
----------------------------------------------------------------