template: page-w-toc title: Creating tables of model estimates menu: memisc
The “mtable” function¶
In conjunction with LaTeX, the output of the mtable()
function of the package can produce output as can be seen in the following example (which is LaTeX converted into a png-file):
This LaTeX output was generated by the following code:
# First a couple of models are run:
model1 <- glm((vote3=="Truman")~occup4,data=vote.48,
family="binomial")
model2 <- glm((vote3=="Truman")~total.income,data=vote.48,
family="binomial")
model3 <- glm((vote3=="Truman")~occup4+total.income,data=vote.48,
family="binomial")
model4 <- glm((vote3=="Truman")~relig3,data=vote.48,
family="binomial")
model5 <- glm((vote3=="Truman")~occup4+relig3,data=vote.48,
family="binomial")
# then an mtable object is produced, relabelled and converted
# to LaTeX:
mt145 <- mtable("Model 1"=model1,
"Model 4"=model4,
"Model 5"=model5,
summary.stats=c("Nagelkerke R-sq.","Deviance","AIC","N")
)
mt145 <- relabel(mt145,
"[(]Intercept[)]"="\\\\emph{Intercept}",
occup4="Occup. class",
relig3="Religion",
gsub=TRUE)
ltx.m145 <- toLatex(mt145,ddigits=5)
writeLines(ltx.m145,
con="somewhere/mt145.tex")
Creating of this output involves the following steps: First, mtable()
is called
mt145 <- mtable("Model 1"=model1,
"Model 4"=model4,
"Model 5"=model5,
summary.stats=c("Nagelkerke R-sq.","Deviance","AIC","N")
)
The resulting object, if printed to the R-console, looks like so:
print(mt145)
Calls:
Model 1: glm(formula = (vote3 == "Truman") ~ occup4, family = "binomial",
data = vote.48)
Model 4: glm(formula = (vote3 == "Truman") ~ relig3, family = "binomial",
data = vote.48)
Model 5: glm(formula = (vote3 == "Truman") ~ occup4 + relig3, family = "binomial",
data = vote.48)
==================================================================================
Model 1 Model 4 Model 5
----------------------------------------------------------------------------------
(Intercept) -1.401*** -0.213 -1.687***
(0.271) (0.126) (0.294)
occup4: Other white collar/Upper white collar 1.368*** 1.287***
(0.373) (0.381)
occup4: Blue collar/Upper white collar 2.448*** 2.385***
(0.327) (0.337)
occup4: Farmer/Upper white collar 1.826*** 2.039***
(0.413) (0.426)
relig3: Catholic/Protestant 0.877*** 0.685*
(0.243) (0.292)
relig3: Other,none/Protestant 0.975** 1.191**
(0.347) (0.441)
----------------------------------------------------------------------------------
Nagelkerke R-sq. 0.2 0.1 0.3
Deviance 404.2 537.7 393.1
AIC 412.2 543.7 405.1
N 344 402 344
==================================================================================
Second, the result of mtable()
is “embellished” using a call to relabel()
:
mt145 <- relabel(mt145,
"[(]Intercept[)]"="\\\\emph{Intercept}",
occup4="Occup. class",
relig3="Religion",
gsub=TRUE)
Third, the relabelled objected is converted into LaTeX and written to a file:
ltx.m145 <- toLatex(mt145,ddigits=5)
writeLines(ltx.m145,
con="somewhere/mt145.tex")
mtable()
can also be used to generate HTML-formatted tables of estimates that can be included into word-processor software such as LibreOffice or MS-Word.
# We get rid of the LaTeX formatting ...
mt145 <- relabel(mt145,
"\\emph{Intercept}"="<em>Intercept</em>",
fixed=TRUE)
show_html(mt145)
Model 1 | Model 4 | Model 5 | |||||||
Intercept | −1 | . | 401*** | −0 | . | 213 | −1 | . | 687*** |
(0 | . | 271) | (0 | . | 126) | (0 | . | 294) | |
Occup. class: Other white collar/Upper white collar | 1 | . | 368*** | 1 | . | 287*** | |||
(0 | . | 373) | (0 | . | 381) | ||||
Occup. class: Blue collar/Upper white collar | 2 | . | 448*** | 2 | . | 385*** | |||
(0 | . | 327) | (0 | . | 337) | ||||
Occup. class: Farmer/Upper white collar | 1 | . | 826*** | 2 | . | 039*** | |||
(0 | . | 413) | (0 | . | 426) | ||||
Religion: Catholic/Protestant | 0 | . | 877*** | 0 | . | 685* | |||
(0 | . | 243) | (0 | . | 292) | ||||
Religion: Other,none/Protestant | 0 | . | 975** | 1 | . | 191** | |||
(0 | . | 347) | (0 | . | 441) | ||||
Nagelkerke R-sq. | 0 | . | 2 | 0 | . | 1 | 0 | . | 3 |
Deviance | 404 | . | 2 | 537 | . | 7 | 393 | . | 1 |
AIC | 412 | . | 2 | 543 | . | 7 | 405 | . | 1 |
N | 344 | 402 | 344 |
Choosing what information is presented in the table and how {#displopt}¶
mtable()
allows to determine what and how additional information accompanies
(coefficient) estimates in model tables, i.e. whether
- standard errors
- p-values
- symbols for statistical significance (for regression astrologists) or
- confidence intervals
are displayed and whether additional information
- appears below estimates
- or to their right.
Further mtable()
allows to specify which summary statistics are shown. In general,
the way model estimated are represented can be further customized as described further below.
Estimates, standard errors, confidence intervals etc. {#standard-errors-confidence-intervals}¶
The chief method to determine how coefficient estmates are shown and what and how additional
information is provided is by using the coef.style=
argument of mtable
with which
a pre-defined or user-provided template is selected. To demonstrate this, we start with
the ‘standard’ way in which coefficient estimates are presented:
library(memisc)
lm0 <- lm(sr ~ pop15 + pop75, data = LifeCycleSavings)
lm1 <- lm(sr ~ dpi + ddpi, data = LifeCycleSavings)
lm2 <- lm(sr ~ pop15 + pop75 + dpi + ddpi, data = LifeCycleSavings)
mtable("Model 1"=lm0,"Model 2"=lm1,"Model 3"=lm2,
summary.stats=c("R-squared","N"))
Model 1 | Model 2 | Model 3 | |||||||
(Intercept) | 30 | . | 628*** | 6 | . | 360*** | 28 | . | 566*** |
(7 | . | 409) | (1 | . | 252) | (7 | . | 355) | |
pop15 | −0 | . | 471** | −0 | . | 461** | |||
(0 | . | 147) | (0 | . | 145) | ||||
pop75 | −1 | . | 934 | −1 | . | 691 | |||
(1 | . | 041) | (1 | . | 084) | ||||
dpi | 0 | . | 001 | −0 | . | 000 | |||
(0 | . | 001) | (0 | . | 001) | ||||
ddpi | 0 | . | 529* | 0 | . | 410* | |||
(0 | . | 210) | (0 | . | 196) | ||||
R-squared | 0 | . | 3 | 0 | . | 2 | 0 | . | 3 |
N | 50 | 50 | 50 |
mtable("Model 1"=lm0,"Model 2"=lm1,"Model 3"=lm2,
coef.style="stat",
summary.stats=c("R-squared","N"))
Model 1 | Model 2 | Model 3 | |||||||
(Intercept) | 30 | . | 628*** | 6 | . | 360*** | 28 | . | 566*** |
(4 | . | 134) | (5 | . | 080) | (3 | . | 884) | |
pop15 | −0 | . | 471** | −0 | . | 461** | |||
(−3 | . | 207) | (−3 | . | 189) | ||||
pop75 | −1 | . | 934 | −1 | . | 691 | |||
(−1 | . | 858) | (−1 | . | 561) | ||||
dpi | 0 | . | 001 | −0 | . | 000 | |||
(1 | . | 962) | (−0 | . | 362) | ||||
ddpi | 0 | . | 529* | 0 | . | 410* | |||
(2 | . | 517) | (2 | . | 088) | ||||
R-squared | 0 | . | 3 | 0 | . | 2 | 0 | . | 3 |
N | 50 | 50 | 50 |
mtable("Model 1"=lm0,"Model 2"=lm1,"Model 3"=lm2,
coef.style="ci",
summary.stats=c("R-squared","N"))
Model 1 | Model 2 | Model 3 | |||||||
(Intercept) | 30 | . | 628 | 6 | . | 360 | 28 | . | 566 |
[15 | . | 724 | [3 | . | 841 | [13 | . | 753 | |
45 | . | 532] | 8 | . | 879] | 43 | . | 379] | |
pop15 | −0 | . | 471 | −0 | . | 461 | |||
[−0 | . | 766 | [−0 | . | 753 | ||||
−0 | . | 175] | −0 | . | 170] | ||||
pop75 | −1 | . | 934 | −1 | . | 691 | |||
[−4 | . | 028 | [−3 | . | 874 | ||||
0 | . | 160] | 0 | . | 491] | ||||
dpi | 0 | . | 001 | −0 | . | 000 | |||
[−0 | . | 000 | [−0 | . | 002 | ||||
0 | . | 002] | 0 | . | 002] | ||||
ddpi | 0 | . | 529 | 0 | . | 410 | |||
[0 | . | 106 | [0 | . | 015 | ||||
0 | . | 952] | 0 | . | 805] | ||||
R-squared | 0 | . | 3 | 0 | . | 2 | 0 | . | 3 |
N | 50 | 50 | 50 |
mtable("Model 1"=lm0,"Model 2"=lm1,"Model 3"=lm2,
coef.style="ci.horizontal",
summary.stats=c("R-squared","N"))
Model 1 | Model 2 | Model 3 | |||||||||||||||||||||||||
(Intercept) | 30 | . | 628 | [15 | . | 724 | 45 | . | 532] | 6 | . | 360 | [3 | . | 841 | 8 | . | 879] | 28 | . | 566 | [13 | . | 753 | 43 | . | 379] |
pop15 | −0 | . | 471 | [−0 | . | 766 | −0 | . | 175] | −0 | . | 461 | [−0 | . | 753 | −0 | . | 170] | |||||||||
pop75 | −1 | . | 934 | [−4 | . | 028 | 0 | . | 160] | −1 | . | 691 | [−3 | . | 874 | 0 | . | 491] | |||||||||
dpi | 0 | . | 001 | [−0 | . | 000 | 0 | . | 002] | −0 | . | 000 | [−0 | . | 002 | 0 | . | 002] | |||||||||
ddpi | 0 | . | 529 | [0 | . | 106 | 0 | . | 952] | 0 | . | 410 | [0 | . | 015 | 0 | . | 805] | |||||||||
R-squared | 0 | . | 3 | 0 | . | 2 | 0 | . | 3 | ||||||||||||||||||
N | 50 | 50 | 50 |
mtable("Model 1"=lm0,"Model 2"=lm1,"Model 3"=lm2,
coef.style="ci.se.horizontal",
summary.stats=c("R-squared","N"))
Model 1 | Model 2 | Model 3 | ||||||||||||||||
(Intercept) | 30 | . | 628 | (7 | . | 409) | 6 | . | 360 | (1 | . | 252) | 28 | . | 566 | (7 | . | 355) |
[15 | . | 724 | 45 | . | 532] | [3 | . | 841 | 8 | . | 879] | [13 | . | 753 | 43 | . | 379] | |
pop15 | −0 | . | 471 | (0 | . | 147) | −0 | . | 461 | (0 | . | 145) | ||||||
[−0 | . | 766 | −0 | . | 175] | [−0 | . | 753 | −0 | . | 170] | |||||||
pop75 | −1 | . | 934 | (1 | . | 041) | −1 | . | 691 | (1 | . | 084) | ||||||
[−4 | . | 028 | 0 | . | 160] | [−3 | . | 874 | 0 | . | 491] | |||||||
dpi | 0 | . | 001 | (0 | . | 001) | −0 | . | 000 | (0 | . | 001) | ||||||
[−0 | . | 000 | 0 | . | 002] | [−0 | . | 002 | 0 | . | 002] | |||||||
ddpi | 0 | . | 529 | (0 | . | 210) | 0 | . | 410 | (0 | . | 196) | ||||||
[0 | . | 106 | 0 | . | 952] | [0 | . | 015 | 0 | . | 805] | |||||||
R-squared | 0 | . | 3 | 0 | . | 2 | 0 | . | 3 | |||||||||
N | 50 | 50 | 50 |
# Why would one want to have letters instead? I have no idea, but
# some Germen authors/editors seem to like it that way ...
mtable("Model 1"=lm0,"Model 2"=lm1,"Model 3"=lm2,
signif.symbols=c("<sup>a</sup>"=.05,
"<sup>b</sup>"=.01,
"<sup>c</sup>"=.001),
summary.stats=c("R-squared","N"))
Model 1 | Model 2 | Model 3 | |||||||
(Intercept) | 30 | . | 628c | 6 | . | 360c | 28 | . | 566c |
(7 | . | 409) | (1 | . | 252) | (7 | . | 355) | |
pop15 | −0 | . | 471b | −0 | . | 461b | |||
(0 | . | 147) | (0 | . | 145) | ||||
pop75 | −1 | . | 934 | −1 | . | 691 | |||
(1 | . | 041) | (1 | . | 084) | ||||
dpi | 0 | . | 001 | −0 | . | 000 | |||
(0 | . | 001) | (0 | . | 001) | ||||
ddpi | 0 | . | 529a | 0 | . | 410a | |||
(0 | . | 210) | (0 | . | 196) | ||||
R-squared | 0 | . | 3 | 0 | . | 2 | 0 | . | 3 |
N | 50 | 50 | 50 |
Summary statistics¶
In general there is a certain variety of summary statistics available in mtable()
. What
statistics these are depends on the statistical model in question and the
facilities provided by the corresponding getSummary()
method (see below). If
mtable()
is called without the summary.stats=
argument all available summary statistics
are shown:
mtable("Model 1"=lm0,"Model 2"=lm1,"Model 3"=lm2)
Model 1 | Model 2 | Model 3 | |||||||
(Intercept) | 30 | . | 628*** | 6 | . | 360*** | 28 | . | 566*** |
(7 | . | 409) | (1 | . | 252) | (7 | . | 355) | |
pop15 | −0 | . | 471** | −0 | . | 461** | |||
(0 | . | 147) | (0 | . | 145) | ||||
pop75 | −1 | . | 934 | −1 | . | 691 | |||
(1 | . | 041) | (1 | . | 084) | ||||
dpi | 0 | . | 001 | −0 | . | 000 | |||
(0 | . | 001) | (0 | . | 001) | ||||
ddpi | 0 | . | 529* | 0 | . | 410* | |||
(0 | . | 210) | (0 | . | 196) | ||||
R-squared | 0 | . | 3 | 0 | . | 2 | 0 | . | 3 |
adj. R-squared | 0 | . | 2 | 0 | . | 1 | 0 | . | 3 |
sigma | 3 | . | 9 | 4 | . | 2 | 3 | . | 8 |
F | 8 | . | 3 | 4 | . | 5 | 5 | . | 8 |
p | 0 | . | 0 | 0 | . | 0 | 0 | . | 0 |
Log-likelihood | −137 | . | 8 | −141 | . | 0 | −135 | . | 1 |
Deviance | 726 | . | 2 | 824 | . | 7 | 650 | . | 7 |
AIC | 283 | . | 7 | 290 | . | 0 | 282 | . | 2 |
BIC | 291 | . | 3 | 297 | . | 7 | 293 | . | 7 |
N | 50 | 50 | 50 |
mtable("Model 1"=lm0,"Model 2"=lm1,"Model 3"=lm2,
summary.stats=c("sigma","BIC","N"))
Model 1 | Model 2 | Model 3 | |||||||
(Intercept) | 30 | . | 628*** | 6 | . | 360*** | 28 | . | 566*** |
(7 | . | 409) | (1 | . | 252) | (7 | . | 355) | |
pop15 | −0 | . | 471** | −0 | . | 461** | |||
(0 | . | 147) | (0 | . | 145) | ||||
pop75 | −1 | . | 934 | −1 | . | 691 | |||
(1 | . | 041) | (1 | . | 084) | ||||
dpi | 0 | . | 001 | −0 | . | 000 | |||
(0 | . | 001) | (0 | . | 001) | ||||
ddpi | 0 | . | 529* | 0 | . | 410* | |||
(0 | . | 210) | (0 | . | 196) | ||||
sigma | 3 | . | 9 | 4 | . | 2 | 3 | . | 8 |
BIC | 291 | . | 3 | 297 | . | 7 | 293 | . | 7 |
N | 50 | 50 | 50 |
For more examples regarding the content of the results of mtable()
refer to
the example code in the help page given by ?mable
.
Exporting mtable results¶
Of course you would not only like to see your table of estimates on screen but
also to include it into a documement that reports your findings. memisc()
supports
exporting tables of model estimates (i.e. results of mtable()
)
into LaTeX documents and into formats that
can be read in by word-processing software: tab-delimited format and HTML.
There is no direct way to export model tables into a word-processing format yet,
mainly because there is no (simple) file format standard (OpenDocument may be an
emerging standard, but it is not easy to create files in this format - at least not as easy
as HTML). These various options of exporting the results of mtable()
are discussed in the
following. To this purpose, we return to the example from above and ‘embellish’ a bit
by changing the coefficient labels:
lm0 <- lm(sr ~ pop15 + pop75, data = LifeCycleSavings)
lm1 <- lm(sr ~ dpi + ddpi, data = LifeCycleSavings)
lm2 <- lm(sr ~ pop15 + pop75 + dpi + ddpi, data = LifeCycleSavings)
mt123 <- mtable("Model 1"=lm0,"Model 2"=lm1,"Model 3"=lm2,
summary.stats=c("R-squared","N"))
mt123 <- relabel(mt123,
"(Intercept)" = "Constant",
pop15 = "Percentage of population under 15",
pop75 = "Percentage of population over 75",
dpi = "Real per-capita disposable income",
ddpi = "Growth rate of real per-capita disp. income"
)
mt123
Calls:
Model 1: lm(formula = sr ~ pop15 + pop75, data = LifeCycleSavings)
Model 2: lm(formula = sr ~ dpi + ddpi, data = LifeCycleSavings)
Model 3: lm(formula = sr ~ pop15 + pop75 + dpi + ddpi, data = LifeCycleSavings)
================================================================================
Model 1 Model 2 Model 3
--------------------------------------------------------------------------------
Constant 30.628*** 6.360*** 28.566***
(7.409) (1.252) (7.355)
Percentage of population under 15 -0.471** -0.461**
(0.147) (0.145)
Percentage of population over 75 -1.934 -1.691
(1.041) (1.084)
Real per-capita disposable income 0.001 -0.000
(0.001) (0.001)
Growth rate of real per-capita disp. income 0.529* 0.410*
(0.210) (0.196)
--------------------------------------------------------------------------------
R-squared 0.3 0.2 0.3
N 50 50 50
================================================================================
LaTeX Format¶
The first format to export mtable()
results into is TeX/LaTeX simply because this
is the format in which the author of this package usually writes his papers. This is
achieved by, first, applying the function toLatex()
to the results of mtable()
,
which tranlates them into a character string containing TeX/LaTeX code and, second,
using writeLines()
to send this character string into a text file.
This was already shown at the beginning, but we take a closer look at it here.
Continuing the example immediately above, we call toLatex()
to see the TeX/LaTeX code:
toLatex(mt123)
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% Calls:
% Model 1: lm(formula = sr ~ pop15 + pop75, data = LifeCycleSavings)
% Model 2: lm(formula = sr ~ dpi + ddpi, data = LifeCycleSavings)
% Model 3: lm(formula = sr ~ pop15 + pop75 + dpi + ddpi, data = LifeCycleSavings)
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\begin{tabular}{lD{.}{.}{3}cD{.}{.}{3}cD{.}{.}{3}}
\toprule
&\multicolumn{1}{c}{Model 1}&&\multicolumn{1}{c}{Model 2}&&\multicolumn{1}{c}{Model 3}\\
\midrule
Constant&30.628^{***}&&6.360^{***}&&28.566^{***}\\
&(7.409)&&(1.252)&&(7.355)\\
Percentage of population under 15&-0.471^{**}&&&&-0.461^{**}\\
&(0.147)&&&&(0.145)\\
Percentage of population over 75&-1.934&&&&-1.691\\
&(1.041)&&&&(1.084)\\
Real per-capita disposable income&&&0.001&&-0.000\\
&&&(0.001)&&(0.001)\\
Growth rate of real per-capita disp. income&&&0.529^{*}&&0.410^{*}\\
&&&(0.210)&&(0.196)\\
\midrule
R-squared&0.3&&0.2&&0.3\\
N&50&&50&&50\\
\bottomrule
\end{tabular}
After formatting with LaTex, this may look like this:
It should be noted that toLatex()
is a generic function and the “memisc”
package ‘only’ defines a method for “mtable” objects. Alternatively
one could use the call
format(mt123,target="LaTeX")
or even call the internal formatting function itself:
mtable_format_latex(m123)
By default, the TeX/LaTeX code created this way
uses the macros \toprule
, \midrule
, and \bottomrule
provided by the LaTeX package “booktabs”. If you do not like this
package (why shouldn’t anyone?) you can resolve this dependency
by calling toLatex()
, format()
, or mtable_format_latex()
with the optional argument
useBooktabs=FALSE
. Another default dependency is the LaTeX package “dcolumn”,
which is used to make sure that floating point numbers are aligned on their decimal dots.
This dependency can be resolved by the optional argument useDcolumn=FALSE
.
For more aspects of LaTeX output that can be customized see
the help page ?mtable_format_latex
.
Until version 0.97 of “memisc”, creating a text file with TeX/LaTeX code had to
be done in two steps, first creating a text string with the code and then
writing the text string into the file. Since version 0.98 both steps can be done
with a single function call, using write.mtable()
. That is, to write
the LaTeX formatted mtable()
result in mt123
one can simple call:
write.mtable(mt123,format="LaTeX",
file="mt123.tex")
Text file format (tab-delimited and “CSV”)¶
Tab-delimited format is of course best-suited for exporting data frames
or matrices into files, but since the results of mtable()
have a tabular
structure, they can also be exported into this format. Tab-delimited format
is quite simple and can be read by a wide variety of software. However,
this simplicity also means that only the cell contents are
exported while embellishments of the contents (e.g. horizonal alignment of
cells and cell borders) are not.
The following code exports the mtable()
result named mt123
into
a text file in tab-delimited format:
write.mtable(mt123,file="mt123.txt")
After opening this file with LibreWriter, using its “covert text into table” tool, and some manual tweaking the result looks like this:
It is also posslibe export an mtable()
result into “CSV” format and
import it into some spreadsheet software. This would be done so:
write.mtable(mt123,file="mt123.csv",colsep=",")
After opening this file with LibreCalc and some tweaking of the format, the result looks like this:
HTML (for web-pages, knitr reports and word processors)¶
Of course, having to tweak the format of mtable()
results by hand is frustrating, so in order to
make easier to get well-formatted tables, version 0.98 of “memisc” provides for exporting
the results of mtable()
into HTML. HTML is the format of websites, but it can also
imported into contemporary word processing software with little loss in formatting.
Further, if one is using the “Rmarkdown” and “knitr” packages to produced HTML-formatted reports,
it is convenient to have HTML versions of mtable()
results.
To get a file in HTML format that contains the results of mtable()
one can again
use the function write.mtable()
, yet in this case with the option format="HTML"
,
or directly the function write_html()
:
write_html(mt123,file="mt123.html")
The file “mt123.html” generated that way can be included into your favourite word-processing software, e.g. LibreOffice. This is how the table would look like after including it into LibreOffece (and setting the columns to “optimal width”):
To view results of mtable()
in HTML in interactive sessions with
RStudio, one can simply call show_html()
as in
show_html(mt123)
Of course, this document is not an interactive sesssion but produced using
the “knitr” package. In this context, show_html()
used inside an R-chunk
with chunk option results='asis'
and the options setting options(html_viewer="stdout")
.
With the following code one could even make sure that all results of mtable()
in a knitr document
are printed in HTML format:
knit_print.mtable <-function(x,...)
knitr::asis_output(format_html(x))
This “trick” was used previously in this document where the different display options of coefficient estmates were discussed. Thus after this trick, in a knitr document we get
mt123
Model 1 | Model 2 | Model 3 | |||||||
Constant | 30 | . | 628*** | 6 | . | 360*** | 28 | . | 566*** |
(7 | . | 409) | (1 | . | 252) | (7 | . | 355) | |
Percentage of population under 15 | −0 | . | 471** | −0 | . | 461** | |||
(0 | . | 147) | (0 | . | 145) | ||||
Percentage of population over 75 | −1 | . | 934 | −1 | . | 691 | |||
(1 | . | 041) | (1 | . | 084) | ||||
Real per-capita disposable income | 0 | . | 001 | −0 | . | 000 | |||
(0 | . | 001) | (0 | . | 001) | ||||
Growth rate of real per-capita disp. income | 0 | . | 529* | 0 | . | 410* | |||
(0 | . | 210) | (0 | . | 196) | ||||
R-squared | 0 | . | 3 | 0 | . | 2 | 0 | . | 3 |
N | 50 | 50 | 50 |
Adapting mtable to new model classes and other tricks - the API of mtable¶
mtable()
is designed to be easily adapted to all kind of model classes: If there
is a model class like, say, “modcls” then all that is needed to get mtable()
to
report estimates of instances of this model class is to define a function
getSummary.modcls()
, i.e. a method function of objects of
class “modcls”. This function needs to return a list with
components
-
“coef”: A matrix or array with coefficients and additional information. The rows should refer to coefficients, the columns should contain the estimates, standard errors, p-values, lower and upper confidence interval limits. The columns should be labelled “est”, “se”, “stat”, “p”, “lwr”, and “upr”.
For single-equation models, this component should be a matrix. For multiple-equation models, it should be a three-dimensional array, with the third dimension corresponding to the equations.
- “sumstat”: A vector (with named elements) containing model summary statistics, such goodness-of-fit statistics etc.
- “contrasts”: A list of the contrast functions, their names, or contrast matrices; one for each (ordered or unordered) factors present in the model.
- “xlevels”: A list with the names of the levels of the factors present in the model.
- “call”: A language object describing the call that created the model estimates.
To illustrate, here are the results of the method function getSummary.glm()
(which is called when the generic function getSummary()
is applied to
an object of class “glm”):
# Model from the first example at the beginning ...
model1 <- glm((vote3=="Truman")~occup4,data=vote.48,
family="binomial")
getSummary(model1) # or getSummary.glm(model1)
$coef
est se stat p lwr upr
(Intercept) -1.40 0.271 -5.17 2.29e-07 -1.932 -0.87
occup4Other white collar 1.37 0.373 3.67 2.42e-04 0.638 2.10
occup4Blue collar 2.45 0.327 7.48 7.36e-14 1.807 3.09
occup4Farmer 1.83 0.413 4.42 9.85e-06 1.016 2.64
$sumstat
phi LR df p logLik
1.00e+00 7.01e+01 3.00e+00 4.11e-15 -2.02e+02
deviance Aldrich.Nelson McFadden Cox.Snell Nagelkerke
4.04e+02 1.69e-01 1.48e-01 1.84e-01 2.46e-01
AIC BIC N
4.12e+02 4.28e+02 3.44e+02
$contrasts
$contrasts$occup4
[1] "contr.treatment"
$xlevels
$xlevels$occup4
[1] "Upper white collar" "Other white collar" "Blue collar"
[4] "Farmer"
$call
glm(formula = (vote3 == "Truman") ~ occup4, family = "binomial",
data = vote.48)
The definition of this function is available in here and can be used as a starting point for other such method functions.
A demonstration: “mtable” and sandwich estimators of variance¶
The modularity of mtable()
through the use of the generic getSummary()
function allows
other kinds of extensions, e.g. adapting it to the use of “sandwich” estimators of standard errors.
This can be achieved, first, by defining yet another method function of getSummary()
, e.g. the one defined
in the R available here. As a second step, one marks
model estimation results such that this newly defined method function is applied to them
by attaching the appropriate class attribute.
For example to get sandwich estimators of standard errors for “lm”” or “glm”” objects
one can attach the classes “lm_sandwich” or “glm_sandwich”, respectively, as in the following
example:
library(memisc)
library(sandwich)
library(lmtest)
source("getSummary-glm-sandwich.R")
data(Mandible)
fm1 <- lm(length ~ age, data=Mandible, subset=(age <= 28))
fm1.sw <- fm1
class(fm1.sw) <- c("lm_sandwich",class(fm1))
mtable(
"Conventional"=fm1,
"Sandwich"=fm1.sw,
summary.stats=c("R-squared","N"))
Conventional | Sandwich | |||||
(Intercept) | −11 | . | 953*** | −11 | . | 953*** |
(0 | . | 976) | (1 | . | 010) | |
age | 1 | . | 773*** | 1 | . | 773*** |
(0 | . | 048) | (0 | . | 054) | |
R-squared | 0 | . | 9 | 0 | . | 9 |
N | 158 | 158 |
Alternatively, one can use an appropriate getSummary=
argument to mtable()
like in this
example:
fm1 <- lm(length ~ age, data=Mandible, subset=(age <= 28))
fm2 <- lm(length ~ age+I(scale(age)^2), data=Mandible, subset=(age <= 28))
# Using 'conventional' i.e. model-based standard errors:
mtable(fm1,fm2,summary.stats=c("R-squared","N"))
fm1 | fm2 | |||||
(Intercept) | −11 | . | 953*** | −11 | . | 303*** |
(0 | . | 976) | (1 | . | 060) | |
age | 1 | . | 773*** | 1 | . | 754*** |
(0 | . | 048) | (0 | . | 049) | |
I(scale(age)^2) | −0 | . | 362 | |||
(0 | . | 236) | ||||
R-squared | 0 | . | 9 | 0 | . | 9 |
N | 158 | 158 |
# Using sandwich-based standard errors:
mtable(fm1,fm2,
summary.stats=c("R-squared","N"),
getSummary=getSummary.lm_sandwich)
fm1 | fm2 | |||||
(Intercept) | −11 | . | 953*** | −11 | . | 303*** |
(1 | . | 010) | (1 | . | 348) | |
age | 1 | . | 773*** | 1 | . | 754*** |
(0 | . | 054) | (0 | . | 063) | |
I(scale(age)^2) | −0 | . | 362 | |||
(0 | . | 258) | ||||
R-squared | 0 | . | 9 | 0 | . | 9 |
N | 158 | 158 |
mtfm12.conv <- mtable("Model 1"=fm1,
"Model 2"=fm2,
summary.stats=c("R-squared","N"))
mtfm12.sndw <- mtable("Model 1"=fm1,
"Model 2"=fm2,
summary.stats=c("R-squared","N"),
getSummary=getSummary.lm_sandwich)
c(Conventional=mtfm12.conv,Sandwich=mtfm12.sndw)
Conventional | Sandwich | |||||||||||
Model 1 | Model 2 | Model 1 | Model 2 | |||||||||
(Intercept) | −11 | . | 953*** | −11 | . | 303*** | −11 | . | 953*** | −11 | . | 303*** |
(0 | . | 976) | (1 | . | 060) | (1 | . | 010) | (1 | . | 348) | |
age | 1 | . | 773*** | 1 | . | 754*** | 1 | . | 773*** | 1 | . | 754*** |
(0 | . | 048) | (0 | . | 049) | (0 | . | 054) | (0 | . | 063) | |
I(scale(age)^2) | −0 | . | 362 | −0 | . | 362 | ||||||
(0 | . | 236) | (0 | . | 258) | |||||||
R-squared | 0 | . | 9 | 0 | . | 9 | 0 | . | 9 | 0 | . | 9 |
N | 158 | 158 | 158 | 158 |