library(tinytable)
options(tinytable_tt_digits = 3)
options(tinytable_theme_placement_latex_float = "H")
<- mtcars[1:4, 1:5] x
Style
The main styling function for the tinytable
package is style_tt()
. Via this function, you can access three main interfaces to customize tables:
- A general interface to frequently used style choices which works for both HTML and LaTeX (PDF): colors, font style and size, row and column spans, etc. This is accessed through several distinct arguments in the
style_tt()
function, such asitalic
,color
, etc. - A specialized interface which allows users to use the powerful
tabularray
package to customize LaTeX tables. This is accessed by passingtabularray
settings as strings to thetabularray_inner
andtabularray_outer
arguments ofstyle_tt()
. - A specialized interface which allows users to use the powerful
Bootstrap
framework to customize HTML tables. This is accessed by passing CSS declarations and rules to thebootstrap_css
andbootstrap_css_rule
arguments ofstyle_tt()
.
These functions can be used to customize rows, columns, or individual cells. They control many features, including:
- Text color
- Background color
- Widths
- Heights
- Alignment
- Text Wrapping
- Column and Row Spacing
- Cell Merging
- Multi-row or column spans
- Border Styling
- Font Styling: size, underline, italic, bold, strikethrough, etc.
- Header Customization
The style_*()
functions can modify individual cells, or entire columns and rows. The portion of the table that is styled is determined by the i
(rows) and j
(columns) arguments.
Cells, rows, columns
To style individual cells, we use the style_cell()
function. The first two arguments—i
and j
—identify the cells of interest, by row and column numbers respectively. To style a cell in the 2nd row and 3rd column, we can do:
tt(x) |>
style_tt(
i = 2,
j = 3,
background = "black",
color = "white")
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 |
The i
and j
accept vectors of integers to modify several cells at once:
tt(x) |>
style_tt(
i = 2:3,
j = c(1, 3, 4),
italic = TRUE,
color = "orange")
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 |
We can style all cells in a table by omitting both the i
and j
arguments:
tt(x) |> style_tt(color = "orange")
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 |
We can style entire rows by omitting the j
argument:
tt(x) |> style_tt(i = 1:2, color = "orange")
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 |
We can style entire columns by omitting the i
argument:
tt(x) |> style_tt(j = c(2, 4), bold = TRUE)
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 |
The j
argument accepts integer vectors, character vectors, but also a string with a Perl-style regular expression, which makes it easier to select columns by name:
tt(x) |> style_tt(j = c("mpg", "drat"), color = "orange")
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 |
tt(x) |> style_tt(j = "mpg|drat", color = "orange")
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 |
Here we use a “negative lookahead” to exclude certain columns:
tt(x) |> style_tt(j = "^(?!drat|mpg)", color = "orange")
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 |
Of course, we can also call the style_tt()
function several times to apply different styles to different parts of the table:
tt(x) |>
style_tt(i = 1, j = 1:2, color = "orange") |>
style_tt(i = 1, j = 3:4, color = "green")
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 |
Colors
The color
and background
arguments in the style_tt()
function are used for specifying the text color and the background color for cells of a table created by the tt()
function. This argument plays a crucial role in enhancing the visual appeal and readability of the table, whether it’s rendered in LaTeX or HTML format. The way we specify colors differs slightly between the two formats:
For HTML Output:
- Hex Codes: You can specify colors using hexadecimal codes, which consist of a
#
followed by 6 characters (e.g.,#CC79A7
). This allows for a wide range of colors. - Keywords: There’s also the option to use color keywords for convenience. The supported keywords are basic color names like
black
,red
,blue
, etc.
For LaTeX Output:
- Hexadecimal Codes: Similar to HTML, you can use hexadecimal codes. However, in LaTeX, you need to include these codes as strings (e.g.,
"#CC79A7"
). - Keywords: LaTeX supports a different set of color keywords, which include standard colors like
black
,red
,blue
, as well as additional ones likecyan
,darkgray
,lightgray
, etc. - Color Blending: An advanced feature in LaTeX is color blending, which can be achieved using the
xcolor
package. You can blend colors by specifying ratios (e.g.,white!80!blue
orgreen!20!red
). - Luminance Levels: The
ninecolors
package in LaTeX offers colors with predefined luminance levels, allowing for more nuanced color choices (e.g., “azure4”, “magenta8”).
Note that the keywords used in LaTeX and HTML are slightly different.
tt(x) |> style_tt(i = 1:4, j = 1, color = "#FF5733")
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 |
Note that when using Hex codes in a LaTeX table, we need extra declarations in the LaTeX preamble. See ?tt
for details.
Alignment
To align columns, we use a single character, or a string where each letter represents a column:
<- data.frame(
dat a = c("a", "aa", "aaa"),
b = c("b", "bb", "bbb"),
c = c("c", "cc", "ccc"))
tt(dat) |> style_tt(j = 1:3, align = "c")
a | b | c |
---|---|---|
a | b | c |
aa | bb | cc |
aaa | bbb | ccc |
tt(dat) |> style_tt(j = 1:3, align = "lcr")
a | b | c |
---|---|---|
a | b | c |
aa | bb | cc |
aaa | bbb | ccc |
In LaTeX documents (only), we can use decimal-alignment:
<- data.frame(pi = c(pi * 100, pi * 1000, pi * 10000, pi * 100000))
z tt(z) |>
format_tt(j = 1, digits = 8, num_fmt = "significant_cell") |>
style_tt(j = 1, align = "d")
pi |
---|
314.15927 |
3141.5927 |
31415.927 |
314159.27 |
Font size
The font size is specified in em units.
tt(x) |> style_tt(j = "mpg|hp|qsec", fontsize = 1.5)
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 |
Spanning cells (merging cells)
Sometimes, it can be useful to make a cell stretch across multiple colums or rows, for example when we want to insert a label. To achieve this, we can use the colspan
argument. Here, we make the 2nd cell of the 2nd row stretch across three columns and two rows:
tt(x)|> style_tt(
i = 2, j = 2,
colspan = 3,
rowspan = 2,
align = "c",
alignv = "m",
color = "white",
background = "black",
bold = TRUE)
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 |
Here is the original table for comparison:
tt(x)
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 |
Spanning cells can be particularly useful when we want to suppress redundant labels:
<- aggregate(mpg ~ cyl + am, FUN = mean, data = mtcars)
tab <- tab[order(tab$cyl, tab$am),]
tab tab
cyl am mpg
1 4 0 22.90000
4 4 1 28.07500
2 6 0 19.12500
5 6 1 20.56667
3 8 0 15.05000
6 8 1 15.40000
tt(tab, digits = 2) |>
style_tt(i = c(1, 3, 5), j = 1, rowspan = 2, alignv = "t")
cyl | am | mpg |
---|---|---|
4 | 0 | 23 |
4 | 1 | 28 |
6 | 0 | 19 |
6 | 1 | 21 |
8 | 0 | 15 |
8 | 1 | 15 |
The rowspan
feature is also useful to create multi-row labels. For example, in this table there is a linebreak, but all the text fits in a single cell:
<- data.frame(Letters = c("A<br>B", ""), Numbers = c("First", "Second"))
tab
tt(tab) |>
style_tt(bootstrap_class = "table-bordered")
Letters | Numbers |
---|---|
A B |
First |
Second |
Now, we use colspan
to ensure that that cells in the first column take up less space and are combined into one:
tt(tab) |>
style_tt(bootstrap_class = "table-bordered") |>
style_tt(1, 1, rowspan = 2)
Letters | Numbers |
---|---|
A B |
First |
Second |
Headers
The header can be omitted from the table by deleting the column names in the x
data frame:
<- x
k colnames(k) <- NULL
tt(k)
21.0 | 6 | 160 | 110 | 3.90 |
21.0 | 6 | 160 | 110 | 3.90 |
22.8 | 4 | 108 | 93 | 3.85 |
21.4 | 6 | 258 | 110 | 3.08 |
The first is row 0, and higher level headers (ex: column spanning labels) have negative indices like -1. They can be styled as expected:
tt(x) |> style_tt(i = 0, color = "white", background = "black")
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 |
When styling columns without specifying i
, the headers are styled in accordance with the rest of the column:
tt(x) |> style_tt(j = 2:3, color = "white", background = "black")
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 |
Conditional styling
We can use the standard which
function from Base R
to create indices and apply conditional stying on rows. And we can use a regular expression in j
to apply conditional styling on columns:
<- mtcars[1:10, c("mpg", "am", "vs")]
k
tt(k) |>
style_tt(
i = which(k$am == k$vs),
background = "teal",
color = "white")
mpg | am | vs |
---|---|---|
21 | 1 | 0 |
21 | 1 | 0 |
22.8 | 1 | 1 |
21.4 | 0 | 1 |
18.7 | 0 | 0 |
18.1 | 0 | 1 |
14.3 | 0 | 0 |
24.4 | 0 | 1 |
22.8 | 0 | 1 |
19.2 | 0 | 1 |
In versions above 0.4.0 of tinytable
, users can also supply a logical matrix of the same size as x
to indicate which cell should be styled. For example, we can change the colors of certain entries in a correlation matrix as follows:
<- data.frame(cor(mtcars[1:5]))
cormat tt(cormat, digits = 2) |>
style_tt(i = abs(cormat) > .8, background = "black", color = "white")
mpg | cyl | disp | hp | drat |
---|---|---|---|---|
1 | -0.85 | -0.85 | -0.78 | 0.68 |
-0.85 | 1 | 0.9 | 0.83 | -0.7 |
-0.85 | 0.9 | 1 | 0.79 | -0.71 |
-0.78 | 0.83 | 0.79 | 1 | -0.45 |
0.68 | -0.7 | -0.71 | -0.45 | 1 |
Vectorized styling (heatmaps)
The color
, background
, and fontsize
arguments are vectorized. This allows easy specification of different colors in a single call:
tt(x) |>
style_tt(
i = 1:4,
color = c("red", "blue", "green", "orange"))
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 |
When using a single value for a vectorized argument, it gets applied to all values:
tt(x) |>
style_tt(
j = 2:3,
color = c("orange", "green"),
background = "black")
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 |
We can also produce more complex heatmap-like tables to illustrate different font sizes in em units:
# font sizes
<- seq(.1, 2, length.out = 20)
fs
# headless table
<- data.frame(matrix(fs, ncol = 5))
k colnames(k) <- NULL
# colors
<- hcl.colors(20, "Inferno")
bg <- ifelse(as.matrix(k) < 1.7, tail(bg, 1), head(bg, 1))
fg
# table
tt(k, width = .7, theme = "void") |>
style_tt(j = 1:5, align = "ccccc") |>
style_tt(
i = 1:4,
j = 1:5,
color = fg,
background = bg,
fontsize = fs)
0.1 | 0.5 | 0.9 | 1.3 | 1.7 |
0.2 | 0.6 | 1.0 | 1.4 | 1.8 |
0.3 | 0.7 | 1.1 | 1.5 | 1.9 |
0.4 | 0.8 | 1.2 | 1.6 | 2.0 |
Lines (borders)
The style_tt
function allows us to customize the borders that surround eacell of a table, as well horizontal and vertical rules. To control these lines, we use the line
, line_width
, and line_color
arguments. Here’s a brief overview of each of these arguments:
line
: This argument specifies where solid lines should be drawn. It is a string that can consist of the following characters:"t"
: Draw a line at the top of the cell, row, or column."b"
: Draw a line at the bottom of the cell, row, or column."l"
: Draw a line at the left side of the cell, row, or column."r"
: Draw a line at the right side of the cell, row, or column.- You can combine these characters to draw lines on multiple sides, such as
"tbl"
to draw lines at the top, bottom, and left sides of a cell.
line_width
: This argument controls the width of the solid lines in em units (default: 0.1 em). You can adjust this value to make the lines thicker or thinner.line_color
: Specifies the color of the solid lines. You can use color names, hexadecimal codes, or other color specifications to define the line color.
Here is an example where we draw lines around every border (“t”, “b”, “l”, and “r”) of specified cells.
tt(x, theme = "void") |>
style_tt(
i = 0:3,
j = 1:3,
line = "tblr",
line_width = 0.4,
line_color = "orange")
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 |
And here is an example with horizontal rules:
tt(x, theme = "void") |>
style_tt(i = 0, line = "t", line_color = "orange", line_width = 0.4) |>
style_tt(i = 1, line = "t", line_color = "purple", line_width = 0.2) |>
style_tt(i = 4, line = "b", line_color = "orange", line_width = 0.4)
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 |
<- data.frame(1:2, 3:4, 5:6, 7:8)
dat colnames(dat) <- NULL
tt(dat, theme = "void") |>
style_tt(
line = "tblr", line_color = "white", line_width = 0.5,
background = "blue", color = "white")
1 | 3 | 5 | 7 |
2 | 4 | 6 | 8 |
Markdown and Word
Styling for Markdown and Word tables is more limited than for the other formats. In particular:
- The only supported arguments are:
bold
,italic
, andstrikeout
. - Headers inserted by
group_tt()
cannot be styled using thestyle_tt()
function.
These limitations are due to the fact that there is no markdown syntax for the other options (ex: colors and background), and that we create Word documents by converting a markdown table to .docx via the Pandoc software.
One workaround is to style the group headers directly in their definition by using markdown syntax:
1:4, 1:4] |>
mtcars[tt() |>
group_tt(i = list("*Hello*" = 1, "__World__" = 3)) |>
print("markdown")
+------+-----+------+-----+
| mpg | cyl | disp | hp |
+======+=====+======+=====+
| *Hello* |
+------+-----+------+-----+
| 21 | 6 | 160 | 110 |
+------+-----+------+-----+
| 21 | 6 | 160 | 110 |
+------+-----+------+-----+
| __World__ |
+------+-----+------+-----+
| 22.8 | 4 | 108 | 93 |
+------+-----+------+-----+
| 21.4 | 6 | 258 | 110 |
+------+-----+------+-----+