Narrower PDF Kable Tables

R knitr kable learning rmarkdown

This is how you should make narrower kable tables in rmarkdown PDF documents.

Robert M Flight
2019-11-06

TL;DR

Don’t bother trying to roll your own function to make narrower kable tables in a PDF document, just use kableExtra.

Motivation

I’ve been creating tables in a report where I really needed the table to fit, and because I am using PDF output, that means the tables can’t be any wider than the page. As I’m sure many readers might be aware, kable tables will gladly overrun the side of the page if they are too wide. I’ve previously used xtable tables when I’ve had this issue, but I really appreciate the simplicity of kable.

First Solution: Custom Function

After some serious Googling, I discovered the \tiny latex environment to change font sizes. Wrapping pandoc tables in this was a no go, but I discovered that it could be embedded within latex table output. This lead me to create a simple function that allowed me to modify latex formatted tables.

smaller_latex_table = function(kable_table, size = "tiny"){
  split_table = strsplit(kable_table, "\n", )[[1]]
  centering_loc = grepl("centering", split_table)
  top_table = split_table[seq(1, which(centering_loc))]
  bottom_table = split_table[seq(which(centering_loc)+1, length(split_table))]
  new_table = c(top_table,
                paste0("\\", size),
                bottom_table)
  structure(new_table, format = "latex", class = "knitr_kable")
}

This worked! And worked quite well. However, the downside to this is that because I had to explicity use latex tables, the tables didn’t stay in place anymore and floated wherever there was free space in the document. Everything I tried with this to get the tables to hold in place failed. So back to the drawing board.

Second Solution: kableExtra

By this point I’ve spent a whole day’s worth of time trying to get this to work, just for some tables in my report. I had initially tried kableExtra on the suggestion of another StackOverflow post, but I had something odd in my latex environment, and odd things going on with tinyTex install that made some ugly tables. After re-installing tinyTex (no small feat to make it discoverable by apt installed RStudio on Linux), I finally got both smaller tables and held in place tables via kableExtra.

To make the tables fit the width of the page, we use latex_options = 'scale_down'.

For holding them to where they are declared, we use latex_options = 'HOLD_position'. However, this also requires the tex packages longtable and float, which should be declared in the yaml header.

Putting it all together looks like this:

## yaml header content
title: "Title"
author: "Me"
output: 
  pdf_document:
    extra_dependencies: ["longtable", "float"]
## table call
knitr::kable(data.frame) %>%
  kableExtra::kable_styling(latex_options = c("scale_down", "HOLD_position"))

Now the table will fit on the page, and stay where it was declared!

I hope I can save someone else two days of trial and error and crazy Googling!

Corrections

If you see mistakes or want to suggest changes, please create an issue on the source repository.

Reuse

Text and figures are licensed under Creative Commons Attribution CC BY 4.0. Source code is available at https://github.com/rmflight/researchBlog_distill, unless otherwise noted. The figures that have been reused from other sources don't fall under this license and can be recognized by a note in their caption: "Figure from ...".

Citation

For attribution, please cite this work as

Flight (2019, Nov. 6). Deciphering Life: One Bit at a Time: Narrower PDF Kable Tables. Retrieved from https://rmflight.github.io/posts/2019-11-06-narrower-kable-tables/

BibTeX citation

@misc{flight2019narrower,
  author = {Flight, Robert M},
  title = {Deciphering Life: One Bit at a Time: Narrower PDF Kable Tables},
  url = {https://rmflight.github.io/posts/2019-11-06-narrower-kable-tables/},
  year = {2019}
}