10.2 The kableExtra package

The kableExtra package (Zhu 2020) is designed to extend the basic functionality of tables produced using knitr::kable() (see Section 10.1). Since knitr::kable() is simple by design (please feel free to read this as “Yihui is lazy”), it definitely has a lot of missing features that are commonly seen in other packages, and kableExtra has filled the gap perfectly. The most amazing thing about kableExtra is that most of its table features work for both HTML and PDF formats (e.g., making striped tables like the one in Figure 10.1).

This package can be installed from CRAN as usual, or you may try the development version on GitHub (https://github.com/haozhu233/kableExtra):

  1. # install from CRAN
  2. install.packages("kableExtra")
  3. # install the development version
  4. remotes::install_github("haozhu233/kableExtra")

It has extensive documentation at https://haozhu233.github.io/kableExtra/, which provides a lot of examples on how the kable() output can be customized for either HTML or LaTeX output. We recommend that you read its documentation by yourself, and will only present a handful of examples in this section.

The kableExtra package features the pipe operator, %>%. You can pipe the kable() output to the styling functions of kableExtra, e.g.,

  1. library(knitr)
  2. library(kableExtra)
  3. kable(iris) %>%
  4. kable_styling(latex_options = "striped")

10.2.1 Set the font size

The function kable_styling() in kableExtra allows you to style the whole table. For example, you can specify the alignment of the table on the page, the width, and the font size of the table. Below is an example of using a smaller font size:

  1. kable(head(iris, 5), booktabs = TRUE) %>%
  2. kable_styling(font_size = 8)
Sepal.LengthSepal.WidthPetal.LengthPetal.WidthSpecies
5.13.51.40.2setosa
4.93.01.40.2setosa
4.73.21.30.2setosa
4.63.11.50.2setosa
5.03.61.40.2setosa

10.2.2 Style specific rows/columns

The functions row_spec() and column_spec() can be used to style individual rows and columns, respectively. In the example below, we make the first row bold and italic, add a black background to the second and third rows while changing the font color to white, underline the fourth row and change its typeface, rotate the fifth row, and strike out the fifth column:

  1. kable(head(iris, 5), align = 'c', booktabs = TRUE) %>%
  2. row_spec(1, bold = TRUE, italic = TRUE) %>%
  3. row_spec(2:3, color = 'white', background = 'black') %>%
  4. row_spec(4, underline = TRUE, monospace = TRUE) %>%
  5. row_spec(5, angle = 45) %>%
  6. column_spec(5, strikeout = TRUE)
Sepal.LengthSepal.WidthPetal.LengthPetal.WidthSpecies
5.13.51.40.2setosa
4.93.01.40.2setosa
4.73.21.30.2setosa
4.63.11.50.2setosa
5.03.61.40.2setosa

Similarly, you can style individual cells with the cell_spec() function.

10.2.3 Group rows/columns

Rows and columns can be grouped via the functions pack_rows() and add_header_above(), respectively. You can also collapse rows via collapse_rows(), so one cell can span multiple rows. Below is an example that shows a custom table header with grouped columns:

  1. iris2 <- iris[1:5, c(1, 3, 2, 4, 5)]
  2. names(iris2) <- gsub('[.].+', '', names(iris2))
  3. kable(iris2, booktabs = TRUE) %>%
  4. add_header_above(c("Length" = 2, "Width" = 2, " " = 1)) %>%
  5. add_header_above(c("Measurements" = 4, "More attributes" = 1))
Measurements
More attributes
Length
Width
SepalPetalSepalPetalSpecies
5.11.43.50.2setosa
4.91.43.00.2setosa
4.71.33.20.2setosa
4.61.53.10.2setosa
5.01.43.60.2setosa

For the named vector in add_header_above(), the names are the text to be shown in the table header, and the integer values of the vector indicate how many columns a name should span, e.g., "Length" = 2 means Length should span two columns.

Below is an example of pack_rows(). The meaning of its index argument is similar to the argument of add_header_above() as we just explained before.

  1. iris3 <- iris[c(1:2, 51:54, 101:103), ]
  2. kable(iris3[, 1:4], booktabs = TRUE) %>% pack_rows(
  3. index = c("setosa" = 2, "versicolor" = 4, "virginica" = 3)
  4. )
Sepal.LengthSepal.WidthPetal.LengthPetal.Width
setosa
15.13.51.40.2
24.93.01.40.2
versicolor
517.03.24.71.4
526.43.24.51.5
536.93.14.91.5
545.52.34.01.3
virginica
1016.33.36.02.5
1025.82.75.11.9
1037.13.05.92.1

10.2.4 Scaling down wide tables in LaTeX

There are a few features that are specific to the HTML or LaTeX output format. For example, landscape pages only make sense in LaTeX, so the landscape() function in kableExtra only works for LaTeX output. Below we show an example to scale down a table to fit the page (otherwise it would be too wide):

  1. tab <- kable(tail(mtcars, 5), booktabs = TRUE)
  2. tab # original table (too wide)
mpgcyldisphpdratwtqsecvsamgearcarb
Lotus Europa30.4495.11133.771.51316.91152
Ford Pantera L15.88351.02644.223.17014.50154
Ferrari Dino19.76145.01753.622.77015.50156
Maserati Bora15.08301.03353.543.57014.60158
Volvo 142E21.44121.01094.112.78018.61142
  1. tab %>%
  2. kable_styling(latex_options = "scale_down")
mpgcyldisphpdratwtqsecvsamgearcarb
Lotus Europa30.4495.11133.771.51316.91152
Ford Pantera L15.88351.02644.223.17014.50154
Ferrari Dino19.76145.01753.622.77015.50156
Maserati Bora15.08301.03353.543.57014.60158
Volvo 142E21.44121.01094.112.78018.61142

You will not see any differences in the above two tables if you are viewing the HTML version.

References

Zhu, Hao. 2020. kableExtra: Construct Complex Table with Kable and Pipe Syntax. https://CRAN.R-project.org/package=kableExtra.