Tables

Introduction

This guide provides insights into creating and styling tables in Quarto markdown documents and Jupyter notebooks.

Topics covered include:

  • Markdown Tables: Learn to create tables with Markdown, using tools like TablesGenerator for simplicity.
  • Styling Tables: Apply Bootstrap classes to enhance table appearance with styles like .striped and .hover.
  • Adjusting Widths: Control column widths with the tbl-colwidths attribute, for individual tables or across the document.
  • Referencing Tables: Make tables referenceable within the text, including computational tables, by using a tbl- prefix in labels.
  • Grouping Subtables: Organize related sub-tables within a div for a structured layout.
  • Caption Placement: Choose caption locations using tbl-cap-location to position captions effectively.
  • Computational Tables: Display computational tables using Python’s tabulate or R’s kable(), with options for layout and subcaptions.
  • Grid Tables: Explore advanced Markdown grid tables for content-rich cells, with cell content alignment options.

This content serves as a practical resource for enhancing table presentation and functionality in technical documentation.

Markdown Tables

Use onlines tools like TablesGenerator to generate markdown tables.

Classical tables

The : character can be used to specify alignment for columns.

  • --- for default alignment (D)
  • :---- for left-aligned (L)
  • ----: for right-aligned (R)
  • :---: for centered (C)
| D       | L    | R     | C      |
|---------|:-----|------:|:------:|
| 12      | 12   |    12 |   12   |
| 123     | 123  |   123 |  123   |
| 1       | 1    |     1 |   1    |

: Demonstration of classical table syntax
Demonstration of classical table syntax
D L R C
12 12 12 12
123 123 123 123
1 1 1 1

Using Bootstrap classes

List of classes that can be used in tables:

"primary", "secondary", "success", "danger", "warning", "info", "light", "dark", "striped", "hover", "active", "bordered", "borderless", "sm", "responsive", "responsive-sm", "responsive-md", "responsive-lg", "responsive-xl", "responsive-xxl".

For example, using {.striped .hover} in your Markdown will create a table with alternating row colors and highlight rows when you hover over them:

| Col1 | Col2 | Col3 |
|------|------|------|
| A    | B    | C    |
| E    | F    | G    |
| A    | G    | G    |

: Demo table {.striped .hover}
Demo table
Col1 Col2 Col3
A B C
E F G
A G G

Column Widths

Use the tbl-colwidths attribute, which can be added after the caption. For example:

| Col1 | Col2 | Col3 |
|------|------|------|
| A    | B    | C    |
| E    | F    | G    |
| A    | G    | G    |

: Demo table {tbl-colwidths="[75,25]"}
Demo table
Col1 Col2 Col3
A B C
E F G
A G G
Note

Note that, if your table doesn’t have a caption, you can still specify only tbl-colwidths

Column widths can also be specified at the document level (e.g., to have uniform widths across a set of tables):

---
title: "My Document"
format: html
tbl-colwidths: [75,25]
---

Cross References

Tables from Code

  1. Include a tbl- prefix in the label for referencing
  2. Reference tables using @ prefix:
```{python}
#| label: tbl-planets
#| tbl-cap: Astronomical object

from IPython.display import Markdown
from tabulate import tabulate
table = [["A","B","C"],
         ["E","F","G"],
         ["A","G","G"]]
Markdown(tabulate(
  table, 
  headers=["Col1","Col2", "Col3"]
))
```
Table 1: Astronomical object
Col1 Col2 Col3
A B C
E F G
A G G

Referencing the table:

see @tbl-planets.

Output:

see Table 1.

Markdown tables

  1. Add a caption below the table
  2. Include a #tbl- label in braces at the end of the caption.

Example:

| Col1 | Col2 | Col3 |
|------|------|------|
| A    | B    | C    |
| E    | F    | G    |
| A    | G    | G    |

: My Caption {#tbl-letters}

See @tbl-letters.

Output:

Table 2: My Caption
Col1 Col2 Col3
A B C
E F G
A G G

See Table 2.

Using div syntax for cross-referencing tables:

::: {#tbl-letters}

| Col1 | Col2 | Col3 |
|------|------|------|
| A    | B    | C    |
| E    | F    | G    |
| A    | G    | G    |

My Caption

::: 

Subtables

  • To combine sub-tables into one composition, use a div with a main identifier.
  • Assign sub-identifiers and optional captions to each table inside the div.
::: {#tbl-panel layout-ncol=2}
| Col1 | Col2 | Col3 |
|------|------|------|
| A    | B    | C    |
| E    | F    | G    |
| A    | G    | G    |

: First Table {#tbl-first}

| Col1 | Col2 | Col3 |
|------|------|------|
| A    | B    | C    |
| E    | F    | G    |
| A    | G    | G    |

: Second Table {#tbl-second}

Main Caption
:::

See @tbl-panel for details, especially @tbl-second.

Output:

Two tables side-by-side. Both tables have 3 columns and 4 rows. The table on the left is titled '(a) First table'. The table on the right is titled '(b) Second Table'. Centered above both tables is the text 'Table 1: Main Caption'.

Note

Note that the “Main Caption” for the table is provided as the last block within the containing div.

Caption Location

  • Default location is above the table.
  • Use tbl-cap-location to change the location to top, bottom, or margin. For example:
---
tbl-cap-location: top
---

Computations

Using Python. Display markdown table using the Python tabulate package along with the Markdown() function from the IPython display module:

```{python}
#| label: tbl-planet-measures
#| tbl-cap: Astronomical object

from IPython.display import Markdown
from tabulate import tabulate
table = [["A","B","C"],
         ["E","F","G"],
         ["A","G","G"]]
Markdown(tabulate(
  table, 
  headers=["Col1","Col2", "Col3"]
))
```
Table 3: Astronomical object
Col1 Col2 Col3
A B C
E F G
A G G

Using R:

  • Display markdown table using the knitr kable() function.
  • Apply the tbl-cap option to add a caption and the tbl-colwidths option to specify column widths.
```{r}
#| label: tbl-cars
#| tbl-cap: "Cars"
#| tbl-colwidths: [60,40]

kable(head(cars))
```

If your code cell produces multiple tables, you can also specify subcaptions and layout using cell options:

```{python}
#| label: tbl-example
#| tbl-cap: "Example"
#| tbl-subcap: 
#|   - "MPG"
#|   - "Taxis"
#| layout-ncol: 2

import seaborn as sns
from IPython.display import Markdown, display
mpg = sns.load_dataset("mpg").head(10)
taxis = sns.load_dataset("taxis").head(10)

display(Markdown(mpg.to_markdown(index = False)))
display(Markdown(taxis.to_markdown(index = False)))
```

Note that we use the display() function imported from IPython so that we can render multiple outputs from a single cell (by default cells only output their last expression).

```{r}
#| label: tbl-example
#| tbl-cap: "Example"
#| tbl-subcap: 
#|   - "Cars"
#|   - "Pressure"
#| layout-ncol: 2

library(knitr)
kable(head(cars))
kable(head(pressure))
```

Grid Tables

Grid tables are a more advanced type of markdown tables that allow arbitrary block elements (multiple paragraphs, code blocks, lists, etc.). For example:

+-----------+-----------+--------------------+
| Col1      | Col2      | Col3               |
+===========+===========+====================+
| A         | B         | - C1               |
|           |           | - C2               |
+-----------+-----------+--------------------+
| E         | F         | - G1               |
|           |           | - G2               |
+-----------+-----------+--------------------+

: Example of grid table.

Which looks like this when rendered to HTML:

Example of grid table.
Col1 Col2 Col3
A B
  • C1
  • C2
E F
  • G1
  • G2

The row of = separates the header from the table body, and can be omitted for a headerless table. Cells that span multiple columns or rows are not supported.

Alignments can be specified as with classical tables, by putting colons at the boundaries of the separator line after the header:

  • ===: for right-aligned (R)
  • :=== for left-aligned (L)
  • :===: for centered (C)
+---------+--------+------------------+
| R       | L      | C                |
+========:+:=======+:================:+
| A       | B      | C                |
+---------+--------+------------------+

Which looks like this when rendered to HTML:

R L C
A B C

For headerless tables, the colons go on the top line instead:

+----------:+:----------+:--------:+
| A         | B         | C        |
+-----------+-----------+----------+

Which looks like this when rendered to HTML:

A B C

Note that grid tables are quite awkward to write with a plain text editor (because unlike pipe tables, the column indicators must align). Here are some tools that can assist with creating grid tables:

References