Tables

Data

Let’s use the built-in mtcars dataset to create a summary that we’ll progressively format:

library(tidyverse)
library(knitr)
library(kableExtra)

# Create a detailed car summary
data(mtcars)

car_summary <- mtcars %>%
  group_by(cyl) %>%
  summarise(
    count = n(),
    mpg = mean(mpg),
    hp = mean(hp),
    wt = mean(wt),
    disp = mean(disp)
  )

Basic Table

The kable() function from the knitr package is the main tool for creating tables in Quarto:

kable(car_summary)
cyl count mpg hp wt disp
4 11 26.66364 82.63636 2.285727 105.1364
6 7 19.74286 122.28571 3.117143 183.3143
8 14 15.10000 209.21429 3.999214 353.1000

Changing column names

We can edit column names them using the col.names parameter:

kable(car_summary,
  col.names = c("Cylinders", "Count", "MPG", "Horsepower", "Weight", "Displacement")
)
Cylinders Count MPG Horsepower Weight Displacement
4 11 26.66364 82.63636 2.285727 105.1364
6 7 19.74286 122.28571 3.117143 183.3143
8 14 15.10000 209.21429 3.999214 353.1000

Decimal places

The digits parameter controls the number of decimal places for each column. You can specify a vector of integers to set different precisions for each column:

kable(car_summary,
  col.names = c("Cylinders", "Count", "MPG", "Horsepower", "Weight", "Displacement"),
  digits = c(0, 0, 1, 0, 2, 0) # Different precision for each column
)
Cylinders Count MPG Horsepower Weight Displacement
4 11 26.7 83 2.29 105
6 7 19.7 122 3.12 183
8 14 15.1 209 4.00 353

Grouping

Now we can group related columns together using the add_header_above() function from kableExtra. This function creates a row above your table headers that spans multiple columns. To use it:

  1. Create a named vector where each name is the group header text
  2. Each value indicates how many columns that group should span
  3. Use " " for columns you don’t want to group (they’ll show blank in the header row)

In the example below, we leave the first two columns ungrouped (with " " = 2), group “MPG” and “Horsepower” under “Performance” ("Performance" = 2), and group “Weight” and “Displacement” under “Size” ("Size" = 2):

grp_car_summary <-
  kable(car_summary,
    col.names = c("Cylinders", "Count", "MPG", "Horsepower", "Weight", "Displacement"),
    digits = c(0, 0, 1, 0, 2, 0)
  ) %>%
  kable_styling(full_width = FALSE) %>%
  add_header_above(c(" " = 2, "Performance" = 2, "Size" = 2))

grp_car_summary
Performance
Size
Cylinders Count MPG Horsepower Weight Displacement
4 11 26.7 83 2.29 105
6 7 19.7 122 3.12 183
8 14 15.1 209 4.00 353

Table captions

The easiest table captions is to simply type out the caption above thet table in the main text. Just make sure to number the table appropriately.


Table 1: A summary of the `mtcars` dataset, grouped by the number of cylinders. The table shows the count of cars, average miles per gallon (MPG), horsepower, weight, and displacement.

```{r}
kable(car_summary)
```

If you want more control over the caption and automate the numbering, Quarto has a comprehensive system for figure captions in general. For tables, you need to set the label and a tbl-cap parameters in the chunk options. The label is used to reference the table in the text ans must be prefixed by a "tbl-*" string. Thetbl-cap` is the caption itself.

```{r}
#| label: tbl-mtcars-summary
#| tbl-cap: A summary of the `mtcars` dataset, grouped by the number of cylinders. The table shows the count of cars, average miles per gallon (MPG), horsepower, weight, and displacement.

grp_car_summary
```
Table 1: A summary of the mtcars dataset, grouped by the number of cylinders. The table shows the count of cars, average miles per gallon (MPG), horsepower, weight, and displacement.
Performance
Size
Cylinders Count MPG Horsepower Weight Displacement
4 11 26.7 83 2.29 105
6 7 19.7 122 3.12 183
8 14 15.1 209 4.00 353