Groups and labels

library(tinytable)
options(tinytable_tt_digits = 3)
options(tinytable_theme_placement_latex_float = "H")
x <- mtcars[1:4, 1:5]

The group_tt() function can label groups of rows (i) or columns (j).

Rows

The i argument accepts a named list of integers. The numbers identify the positions where row group labels are to be inserted. The names includes the text that should be inserted:

dat <- mtcars[1:9, 1:8]

tt(dat) |>
  group_tt(i = list(
    "I like (fake) hamburgers" = 3,
    "She prefers halloumi" = 4,
    "They love tofu" = 7))
mpg cyl disp hp drat wt qsec vs
21 6 160 110 3.9 2.62 16.5 0
21 6 160 110 3.9 2.88 17 0
22.8 4 108 93 3.85 2.32 18.6 1
21.4 6 258 110 3.08 3.21 19.4 1
18.7 8 360 175 3.15 3.44 17 0
18.1 6 225 105 2.76 3.46 20.2 1
14.3 8 360 245 3.21 3.57 15.8 0
24.4 4 147 62 3.69 3.19 20 1
22.8 4 141 95 3.92 3.15 22.9 1

The numbers in the i list indicate that a label must be inserted at position # in the original table (without row groups). For example,

tt(head(iris)) |>
  group_tt(i = list("After 1" = 2, "After 2" = 3, "After 3" = 4, "After 5" = 6))
Sepal.Length Sepal.Width Petal.Length Petal.Width Species
5.1 3.5 1.4 0.2 setosa
4.9 3 1.4 0.2 setosa
4.7 3.2 1.3 0.2 setosa
4.6 3.1 1.5 0.2 setosa
5 3.6 1.4 0.2 setosa
5.4 3.9 1.7 0.4 setosa
tt(head(iris)) |>
  group_tt(i = list("After 1a" = 2, "After 1b" = 2, "After 5" = 6))
Sepal.Length Sepal.Width Petal.Length Petal.Width Species
5.1 3.5 1.4 0.2 setosa
4.9 3 1.4 0.2 setosa
4.7 3.2 1.3 0.2 setosa
4.6 3.1 1.5 0.2 setosa
5 3.6 1.4 0.2 setosa
5.4 3.9 1.7 0.4 setosa
tt(head(iris)) |>
  group_tt(i = list("After 0" = 1))
Sepal.Length Sepal.Width Petal.Length Petal.Width Species
5.1 3.5 1.4 0.2 setosa
4.9 3 1.4 0.2 setosa
4.7 3.2 1.3 0.2 setosa
4.6 3.1 1.5 0.2 setosa
5 3.6 1.4 0.2 setosa
5.4 3.9 1.7 0.4 setosa

We can style group rows in the same way as regular rows:

tt(dat) |> 
  group_tt(
    i = list(
      "I like (fake) hamburgers" = 3,
      "She prefers halloumi" = 4,
      "They love tofu" = 7)) |>
  style_tt(
    i = c(3, 5, 9),
    align = "c",
    color = "white",
    background = "gray",
    bold = TRUE)
mpg cyl disp hp drat wt qsec vs
21 6 160 110 3.9 2.62 16.5 0
21 6 160 110 3.9 2.88 17 0
22.8 4 108 93 3.85 2.32 18.6 1
21.4 6 258 110 3.08 3.21 19.4 1
18.7 8 360 175 3.15 3.44 17 0
18.1 6 225 105 2.76 3.46 20.2 1
14.3 8 360 245 3.21 3.57 15.8 0
24.4 4 147 62 3.69 3.19 20 1
22.8 4 141 95 3.92 3.15 22.9 1

Automatic row groups

We can use the group_tt() function to group rows and label them using spanners (almost) automatically. For example,

# subset and sort data
df <- mtcars |> head(10) |> sort_by(~ am)

# identify row indices
indices <- tapply(1:nrow(df), df$am, \(x) x[1], simplify = FALSE)

# draw table
tt(df) |> group_tt(i = indices)
mpg cyl disp hp drat wt qsec vs am gear carb
21.4 6 258 110 3.08 3.21 19.4 1 0 3 1
18.7 8 360 175 3.15 3.44 17 0 0 3 2
18.1 6 225 105 2.76 3.46 20.2 1 0 3 1
14.3 8 360 245 3.21 3.57 15.8 0 0 3 4
24.4 4 147 62 3.69 3.19 20 1 0 4 2
22.8 4 141 95 3.92 3.15 22.9 1 0 4 2
19.2 6 168 123 3.92 3.44 18.3 1 0 4 4
21 6 160 110 3.9 2.62 16.5 0 1 4 4
21 6 160 110 3.9 2.88 17 0 1 4 4
22.8 4 108 93 3.85 2.32 18.6 1 1 4 1

Columns

The syntax for column groups is very similar, but we use the j argument instead. The named list specifies the labels to appear in column-spanning labels, and the values must be a vector of consecutive and non-overlapping integers that indicate which columns are associated to which labels:

tt(dat) |> 
  group_tt(
    j = list(
      "Hamburgers" = 1:3,
      "Halloumi" = 4:5,
      "Tofu" = 7))
Hamburgers Halloumi Tofu
mpg cyl disp hp drat wt qsec vs
21 6 160 110 3.9 2.62 16.5 0
21 6 160 110 3.9 2.88 17 0
22.8 4 108 93 3.85 2.32 18.6 1
21.4 6 258 110 3.08 3.21 19.4 1
18.7 8 360 175 3.15 3.44 17 0
18.1 6 225 105 2.76 3.46 20.2 1
14.3 8 360 245 3.21 3.57 15.8 0
24.4 4 147 62 3.69 3.19 20 1
22.8 4 141 95 3.92 3.15 22.9 1

Here is a table with both row and column headers, as well as some styling:

dat <- mtcars[1:9, 1:8]
tt(dat) |> 
  group_tt(
    i = list("I like (fake) hamburgers" = 3,
             "She prefers halloumi" = 4,
             "They love tofu" = 7),
    j = list("Hamburgers" = 1:3,
             "Halloumi" = 4:5,
             "Tofu" = 7)) |>
  style_tt(
    i = c(3, 5, 9),
    align = "c",
    background = "teal",
    color = "white") |>
  style_tt(i = -1, color = "teal")
Hamburgers Halloumi Tofu
mpg cyl disp hp drat wt qsec vs
21 6 160 110 3.9 2.62 16.5 0
21 6 160 110 3.9 2.88 17 0
22.8 4 108 93 3.85 2.32 18.6 1
21.4 6 258 110 3.08 3.21 19.4 1
18.7 8 360 175 3.15 3.44 17 0
18.1 6 225 105 2.76 3.46 20.2 1
14.3 8 360 245 3.21 3.57 15.8 0
24.4 4 147 62 3.69 3.19 20 1
22.8 4 141 95 3.92 3.15 22.9 1

We can also stack several extra headers on top of one another:

tt(x) |>
  group_tt(j = list("Foo" = 2:3, "Bar" = 5)) |>
  group_tt(j = list("Hello" = 1:2, "World" = 4:5))
Hello World
Foo Bar
mpg cyl disp hp drat
21 6 160 110 3.9
21 6 160 110 3.9
22.8 4 108 93 3.85
21.4 6 258 110 3.08