APA Tables Using RMarkdown

Posted by Andy on Thursday, January 9, 2020

Often it is useful to format table output to make it look good or to adhere a particular style (e.g., APA). There are several packages that help in this endeavor when working in an Rmarkdown document. When I create tables using RMarkdown, the primary packages I use are:

  • The kable() function from the knitr package; and
  • Functions from the kableExtra package.

There are many packages for formatting tables, among others, include the flextable package, the gt package, the huxtable package, and the expss package. I have tried all of these and many more. I settled on knitr because of its robustness and ease of use—along with kableExtra, it can create almost any table I can imagine using a general set of syntax.

I also use LaTeX and PDF output when I need to really format using the APA style. My experience with HTML and APA is that I can get really close, but there are one or two elements that I can’t seem to get formatted correctly, which varies depending on the package I try. The closest I get with HTML (without using bookdown) seems to be the flextable package. It may also be worth mentioning the papaja package package. This can set up an entire RMarkdown document to adhere to APA formatting, but is beyond the scope of what I typically need.

To illustrate my process for table creation using LaTeX, I will attempt to re-create the following table from the 7th edition of the APA Publication Manual.

Table 7.6 from the 7th edition of the APA Publication Manual (p. 213).

My Process

To begin I will load a few packages.

# Load libraries
library(knitr)
library(kableExtra)
library(tidyverse)

The workhorse function from the knitr package for table creation is the kable() function, and the primary input to the kable() function is a data frame. Below I will set up a data frame to mimic the content from our goal table.

tab_01 = data.frame(
  scale = c("BAS-T", "SR", "BDI", "ASRM", "M-SRM"),
  high = c("46.17 (2.87)", "17.94 (1.88)", "7.11 (6.50)", 
           "6.46 (4.01)", "11.05 (3.36)"),
  moderate = c("37.99 (1.32)", "11.52 (1.84)", "6.18 (6.09)", 
               "5.63 (3.69)", "11.76 (2.75)"),
  p = c("<.001", "<.001", ".254", ".109", ".078")
)

Although I simply entered the data values, this data frame could also be created as the ouput of one or more functions.

We can now use the kable() function to rename the columns, round numeric values (which we don’t have since I entered the numbers as quoted text), set alignment for each column, set a caption, etc.

kable(
  tab_01,
  format = "latex",
  booktabs = TRUE,
  col.names = c("Scale", "High BAS group", "Moderate BAS group", "p"),
  align = c("l", "c", "c", "c"),
  caption = "Means and Standard Deviations of Scores on Baseline Measures"
  )

This gets us 90% of the way there. There are a few things to do to make this ready for primetime. First we will italicize the “p” in the header row. To do this we need to use some LaTeX commands. So that it compiles correctly we will also add the argument escape=FALSE into the kable() function.

kable(
  tab_01,
  format = "latex",
  booktabs = TRUE,
  escape = FALSE,
  col.names = c("Scale", "High BAS group", "Moderate BAS group", "\\textit{p}"),
  align = c("l", "c", "c", "c"),
  caption = "Means and Standard Deviations of Scores on Baseline Measures"
  )

To further format the table we will use functionality from the kableExtra package. To do this we pipe the kable() output into the functions from the kableExtra package. Here I center all of the column headings using the rowspec() function and also style the table to be full page width.

kable(
  tab_01,
  format = "latex",
  booktabs = TRUE,
  escape = FALSE,
  col.names = c("Scale", "High BAS group", "Moderate BAS group", "\\textit{p}"),
  align = c("l", "c", "c", "c"),
  caption = "Means and Standard Deviations of Scores on Baseline Measures"
  ) %>%
  row_spec(row = 0, align = "c") %>%
  kable_styling(full_width = TRUE)

Next we will add the footnote using the footnote() function from kableExtra. The different arguments I use here are:

  • general_title= Allows you to change the default footnote title from Note: to Note.
  • general= The actual text of the footnote
  • threeparttable=TRUE will force the width of caption and footnotes be the width of the original table. It’s useful when you have long paragraph of footnotes.
  • footnote_as_chunk=TRUE sets the footnote to printed in a chunk (without line break after Note.).

To make the threeparttable= argument work we also need to add longtable=TRUE into the kable() function.

kable(
  tab_01,
  format = "latex",
  booktabs = TRUE,
  escape = FALSE,
  longtable = TRUE,
  col.names = c("Scale", "High BAS group", "Moderate BAS group", "\\textit{p}"),
  align = c("l", "c", "c", "c"),
  caption = "Means and Standard Deviations of Scores on Baseline Measures"
  ) %>%
  row_spec(row = 0, align = "c") %>%
  kable_styling(full_width = TRUE) %>%
  footnote(
    general_title = "Note.",
    general = "Standard deviations are presented in parentheses. BAS = Behavioral Activation System; BAS-T = Behavioral Activation System-Total sores from the Behavioral Inhibition System/Behavioral Activation System Scales; SR = Sensitivity to Reward scores from the Sensitivity to Punishment and Sensitivity to Reward Questionnaire; BDI = Beck Depression Inventory scores; ASRM = Altman Self-Rating Mania Scale scores; M-SRM = Modified Social Rhythm Metric Regularity scores.",
    threeparttable = TRUE,
    footnote_as_chunk = TRUE
    )

Lastly we need to adjust the captioning. This requires us to use the caption package from LaTeX. (Note: This is not an R package!) We load the caption package in the YAML of our RMarkdown document. If you are using tinytex this package will install automatically if you do not have it. Otherwise, you may need to install this LaTeX package. We add the header-include: field into our YAML and then use the \usepackage{} LaTeX function to load the caption package. Here is what this will look like:

---
title: "Untitled"
author: "Andrew Zieffler"
date: "1/10/2020"
output: pdf_document
header-includes:
   - \usepackage{caption}
---   

The caption package includes the captionsetup{} function. To format the caption using the APA formatting we need:

  • Table caption in italics
  • Table numbering in boldface
  • Line separating the table number and caption

This can be included in the YAML as well:

---
title: "Untitled"
author: "Andrew Zieffler"
date: "1/10/2020"
output: pdf_document
header-includes:
   - \usepackage{caption}
   - \captionsetup[table]{textfont={it}, labelfont={bf}, singlelinecheck=false, labelsep=newline}
---

For more options see here. You can also set u your figure captioning in a similar way; use figure instead of `table’ between the square brackets.

Shazaam! We have a nice looking table that is formatted to APA style.