knitr::opts_chunk$set( collapse = TRUE, comment = "#>" )
The Bullock
package provides three functions to help you make tables:
regTable()
, latexTable()
, and latexTablePDF()
. The functions can be
used separately but are designed to be used together. regTable()
generates a
matrix of regression results, latexTable()
turns it into LaTeX code, and
latexTablePDF()
renders the LaTeX code as PDF.
Many other packages will help you to make tables. The outstanding feature of this package is that it offers you less. For example, this package offers you no opportunity to change colors or fonts, to add rules and borders in inappropriate places, or to create tables with baroque layouts. This package makes easy things easy, and it makes creating bad tables quite difficult.
The other major feature of this package is that it makes tables easier to read by prioritizing the careful use of white space between different table elements. With that in mind, it produces "Tufte tables," in which standard errors are printed to the right of their estimates and in smaller type. Relative to conventional formatting---which places standard errors below the estimates and in parentheses---the formatting used here makes it easier for readers to instantly identify the information that they need. To my knowledge, the table design used here was first used in Edward Tufte's essay on The Cognitive Style of PowerPoint.
library(Bullock)
Begin by generating a few regression objects and then putting the results into a matrix:
data(iris) lm1 <- lm(Sepal.Length ~ Petal.Length, data = iris) lm2 <- lm(Sepal.Length ~ Petal.Length + Petal.Width, data = iris) lm3 <- lm(Sepal.Length ~ Petal.Length * Petal.Width, data = iris) lmList <- list(lm1, lm2, lm3) rT1 <- regTable(lmList) rT1
Then use latexTable()
convert the matrix into LaTeX code:
lT1 <- latexTable( mat = rT1, rowNames = c("Intercept", "Petal length", "Petal width", "Petal length $\\times$ petal width"), colNames = lt_colNumbers(), caption = '\\textit{Sepal length as a function of petal length and petal width.}' ) head(lT1) tail(lT1)
You see that lT1
contains LaTeX code for a macro called myTable
. You can
render the table directly to a PDF file by calling latexTablePDF()
:
latexTablePDF(lT1, outputFilenameStem = 'irisTable')
Or you can write the macro to a .tex file:
latexTablePDF(lT1, outputFilenameStem = 'irisTable', writeTex = TRUE)
::: {.marginTopN4p5ex}
The .tex file can then be inserted into your master LaTeX document by adding
\input{irisTable.tex}
or \include{irisTable.tex}
into your master LaTeX document.
(For more on \input
and \include
, see
the LaTeX wikibook
and Stack Overflow.)
:::
update()
Suppose that you produce a complex table with a long latexTable()
call. You
then want to produce a new table that is similar. For example, you may want to
produce a new table with different data but all of the same design features
(the same row names, the same spacing, etc.). You could issue another long
latexTable()
call to produce the new table. Or you could just use update()
:
lm1v <- update(lm1, subset = (Species == 'versicolor')) lm2v <- update(lm2, subset = (Species == 'versicolor')) lm3v <- update(lm3, subset = (Species == 'versicolor')) rT2 <- regTable(list(lm1v, lm2v, lm3v)) lT2 <- update(lT1, mat = rT2) lT2[23:26] # just showing the data rows
Instead of using update()
, you may prefer to edit your table "by hand" after
it is produced by latexTable()
. This is easy to do, because
latexTable()
returns an object of the "character" class---that is, a vector
of strings. Each string is a line of LaTeX code. The simple format of the
returned object makes it easy to edit the object before writing it to disk as
a .tex or PDF file:
lT2[24:26] # Capitalize first letter of each word that is preceded by a space lT2[24:26] <- gsub("([[:space:]])([[:alpha:]])", "\\1\\U\\2", lT2[24:26], perl=TRUE) lT2[24:26]
::: {.marginTopN4p5ex .marginBottom4ex}
In practice, you will probably want to tweak tables only when you have unusual
formatting requirements that cannot be satisfied by the latexTable()
options.
:::
headerFooter = FALSE
You may not want to generate standalone .tex or PDF files. Instead, you may
already have the skeleton of a LaTeX table set up in your master LaTeX
document, and you may just want to copy the table rows (specified as LaTeX
code) from R into that skeleton table. This is easy to do with the
headerFooter
argument to latexTable()
:
latexTable( headerFooter = FALSE, mat = rT1, rowNames = c("Intercept", "Petal length", "Petal width", "Petal length $\\times$ petal width"), spacerColumns = c(0, 2, 4) )
latexTable()
in R Markdown and Rnw documentsIt is easy to use latexTable()
in R Markdown and Rnw documents. See
the Using latexTable()
with R Markdown
and Rnw documents
vignette for details.
Ordinary methods for inserting space between columns in LaTeX involve the
\tabcolsep
and \extracolsep
LaTeX lengths. Unfortunately, \cmidrule
and
other commands in the booktabs
package don't recognize that these LaTeX
lengths are spaces between columns. As a result, rules (horizontal lines)
drawn by booktabs
commands extend into the intercolumn region if
\tabcolsep
and \extracolsep
are used to provide intercolumn space. A
similar problem occurs if \hspace
is used to provide intercolumn space.
Thus, to fine-tune the spacing of the LaTeX tables produced by latexTable()
,
blank columns can be inserted at arbitrary positions via the spacerColumns
argument. This is not the simplest way to adjust intercolumn space, but it
solves the problem of positioning horizontal rules. In addition, no other
approach gives you the freedom to insert horizontal space at arbitrary
positions (useful for distinguishing tiers of columns from each other), and no
other approach allows variation in the widths of the spaces between columns.
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.