> head(airquality, n = 6)
R
Ozone Solar.R Wind Temp Month Day1 41 190 7.4 67 5 1
2 36 118 8.0 72 5 2
3 12 149 12.6 74 5 3
4 18 313 11.5 62 5 4
5 NA NA 14.3 56 5 5
6 28 NA 14.9 66 5 6
Generating Latex Tables in R
Introduction
Preparing Latex tables from results of a simulation study or other program can be tedious and time-consuming when done by hand. Especially when the process must be repeated many tables as results are updated to correct mistakes or to investigate unexpected findings. Hours spent manually adjusting formatting of table entries and typing ampersands between them could be spent in better ways. Fortunately, there are some excellent tools in R to help. Taking time to learn the tools and automate your table generation may be worth the investment. We will give a brief example in this post. This is only based on my experience; there are likely even better tools and methods that I have yet to learn.
Objective
Our objective will be to generate a Latex table for the first six rows of the airquality
dataset.
We would also like to meet the following criteria.
- Criteria for formatting of the rendered Latex table.
- Use booktabs and make all separators horizontal lines.
- Use multiline columns to render column names.
- Add several headers which group together columns in the display.
- Specify a caption and a label which can be used in Latex references.
- Request the table to be placed “here”.
- Criteria for table content.
- Include row labels (observation number) in the table as a column.
- Format numbers in a purposeful way.
- Display the
Month
andDay
columns together as a date. - Customize column names to be more descriptive.
- Ensure that the generated Latex code is legible.
- Pad strings in a given column so that they are nicely aligned in the code.
To do this, we will make use of the following tools.
- The Tidyverse framework to manipulate tables.
- The knitr package for reproducible research in R. In particular, we will use the kable function. to generate Latex from data frames.
- The kableExtra package to handle some additional Latex work.
- The built-in
sprintf
function to format table entries.
Preparing the Data Frame
First let us load the packages we will use.
> library(knitr)
R> library(dplyr)
R> library(tibble)
R> library(stringr)
R> library(kableExtra) R
Before converting to Latex, let us format the entries and column names as we would like them to appear.
= head(airquality, n = 6) %>%
tbl rownames_to_column(var = "Num") %>%
mutate(Date = sprintf("%04d-%02d-%02d", 1973, Month, Day)) %>%
mutate(Solar.R = sprintf("%0.2e", Solar.R)) %>%
mutate(TempC = sprintf("%0.2f", 5/9 * (Temp - 32))) %>%
select(Num, Date, Ozone, Solar.R, Wind, TempC)
We have done the following.
- Assemble
Month
andDay
intoDate
, where 1973 is the year which all observations were taken (according to the manual page for the dataset). - Convert
Solar.R
to a string with the original value in scientific notation. - Convert temperature
Temp
from Farenheit to Celcius and call the resultTempC
. - Use
tibble::rownames_to_column
to include row labels in the table as theObs
column.
This produces the following table.
> print(tbl)
R
Num Date Ozone Solar.R Wind TempC1 1 1973-05-01 41 1.90e+02 7.4 19.44
2 2 1973-05-02 36 1.18e+02 8.0 22.22
3 3 1973-05-03 12 1.49e+02 12.6 23.33
4 4 1973-05-04 18 3.13e+02 11.5 16.67
5 5 1973-05-05 NA NA 14.3 13.33
6 6 1973-05-06 28 NA 14.9 18.89
Generating Latex
We can now generate code to display out formatted table as Latex code.
= tbl %>%
out mutate(Solar.R = str_pad(Solar.R, width = 10, side = "left", pad = "\u00A0")) %>%
mutate(Wind = str_pad(Wind, width = 6, side = "left", pad = "\u00A0")) %>%
kable(format = "latex", booktabs = TRUE, linesep = "", align = c("rlrrrr"),
caption = "My formatted airquality table.", label = "airquality",
col.names = c("Number", "Date", "Ozone (PPB)", "Radiation (Ly)",
"Wind (MPH)", "Temp (C)")) %>%
kable_styling(latex_options = c("hold_position")) %>%
add_header_above(c("Observation" = 2, "Solar" = 2, "Weather" = 2))
We have done the following.
Left-pad the
Solar.R
andWind
fields with the unicode “nbsp” character, which will render as a space in our resulting code rather than be ignored, as a regular space would.Use
kable
to generate a Latex table from our data frame. We have specified options such as cell alignments, the caption, and the label, which should be familiar to Latex users. We have also specified descriptive column names here.The option
hold_position
specifies the option!h
for how Latex should place the table.The function
add_header_above
specifies a layer of headers above the column names. These respectively have text “Observation”, “Solar” and “Weather”, and are each two columns wide.
Printing the result yields the following Latex code.
> print(out)
R!h]
\begin{table}[
\centering:airquality}My formatted airquality table.}
\caption{\label{tab
\centering
\begin{tabular}[t]{rlrrrr}
\toprule2}{c}{Observation} & \multicolumn{2}{c}{Solar} & \multicolumn{2}{c}{Weather} \\
\multicolumn{cmidrule(l{3pt}r{3pt}){1-2} \cmidrule(l{3pt}r{3pt}){3-4} \cmidrule(l{3pt}r{3pt}){5-6}
\& Date & Ozone (PPB) & Radiation (Ly) & Wind (MPH) & Temp (C)\\
Number
\midrule1 & 1973-05-01 & 41 & 1.90e+02 & 7.4 & 19.44\\
2 & 1973-05-02 & 36 & 1.18e+02 & 8 & 22.22\\
3 & 1973-05-03 & 12 & 1.49e+02 & 12.6 & 23.33\\
4 & 1973-05-04 & 18 & 3.13e+02 & 11.5 & 16.67\\
5 & 1973-05-05 & NA & NA & 14.3 & 13.33\\
6 & 1973-05-06 & 28 & NA & 14.9 & 18.89\\
\bottomrule
\end{tabular} \end{table}
We now have a Latex table
environment - which is fairly human-readable - that can be copy/pasted into a Latex document, or even included programmatically using Sweave.