LaTeX math formatting text table by Alessio Damato is licensed
under CC BY-SA 3.0 http://creativecommons.org/licenses/by-sa/3.0/ via
Wikimedia Commons.
Columns of text in a data table will generally not be rendered using
the same typeface as numerical value formatted using
format_power()
or format_decimal()
. The
format_text()
function provides an approach to assigning a
typeface to such columns.
Text is delimited by $ ... $
similar to the math markup
applied by format_power()
and format_decimal()
with the addition of LaTeX-style math-text commands such as
\mathrm
, \mathit
, etc. and font size commands
such as \small
or \normalsize
to output one of
the standard typefaces for text.
For example, the default markup for the text “abcde” is given by
"$\\small\\mathrm{abcde}$"
where \\small
controls the font size. As discussed in
other vignettes, the backslash in \small
and
\mathrm
must be “escaped” for rendering, hence the markup
is given by \\small\\mathrm
.
format_text()
Given a character string, vector, or column from a data frame,
format_text()
converts the values to character strings of
the form,
"$\\size\\math*{a}"
where a
is the element to be formatted;
\\size
controls the font size using conventional LaTeX size
commands (\\small
, \\normalsize
,
\\large
, etc.); and \\math*
determines the
font face: plain type is set by \\mathrm
; italics by
\\mathit
; bold by \\mathbf
, sans serif by
\\mathsf
; and monospace (typewriter text) by
\\mathtt
. The string includes markup delimiters
$...$
for rendering as an inline equation in R Markdown or
Quarto Markdown document.
Arguments.
x Text to be formatted. Can be a scalar, a vector, or a column from a data frame. Non-characters are coerced to character class if possible.
face Font face. Possible values are “plain”
(default), “italic”, “bold”, “sans”, or “mono”. Can also be set as a
global option, for example,
options(formatdown.font.face = "sans)
, that can be
overwritten in an individual function call.
size Font size. Possible values are
“scriptsize”, “small” (default), “normalsize”, “large”, or “huge”. Can
also be set as a global option, for example,
options(formatdown.font.size = "normalsize")
, that can be
overwritten in an individual function call.
delim Character vector of length one or two
defining the math markup delimiters. Possible values include
"$"
(default) or "\\("
, both of which create
appropriate left and right delimiters. Custom delimiters can be assigned
if required by one’s TeX processor.
If you are writing your own script to follow along, we use these packages in this vignette:
Format the same column of text using each of the five possible
size
arguments for comparison.
x <- c("low", "med", "high")
# Compare formats
DT <- data.table(
scriptsize = format_text(x, size = "scriptsize"),
small = format_text(x, size = "small"),
normalsize = format_text(x, size = "normalsize"),
large = format_text(x, size = "large"),
huge = format_text(x, size = "huge")
)
knitr::kable(DT, align = "r")
scriptsize | small | normalsize | large | huge |
---|---|---|---|---|
\(\scriptsize\mathrm{low}\) | \(\small\mathrm{low}\) | \(\normalsize\mathrm{low}\) | \(\large\mathrm{low}\) | \(\huge\mathrm{low}\) |
\(\scriptsize\mathrm{med}\) | \(\small\mathrm{med}\) | \(\normalsize\mathrm{med}\) | \(\large\mathrm{med}\) | \(\huge\mathrm{med}\) |
\(\scriptsize\mathrm{high}\) | \(\small\mathrm{high}\) | \(\normalsize\mathrm{high}\) | \(\large\mathrm{high}\) | \(\huge\mathrm{high}\) |
Format the same column of text using each of the five possible
face
arguments for comparison.
# Compare formats
DT <- data.table(
plain = format_text(x, face = "plain"),
italic = format_text(x, face = "italic"),
bold = format_text(x, face = "bold"),
sans = format_text(x, face = "sans"),
mono = format_text(x, face = "mono")
)
knitr::kable(DT, align = "r")
plain | italic | bold | sans | mono |
---|---|---|---|---|
\(\small\mathrm{low}\) | \(\small\mathit{low}\) | \(\small\mathbf{low}\) | \(\small\mathsf{low}\) | \(\small\mathtt{low}\) |
\(\small\mathrm{med}\) | \(\small\mathit{med}\) | \(\small\mathbf{med}\) | \(\small\mathsf{med}\) | \(\small\mathtt{med}\) |
\(\small\mathrm{high}\) | \(\small\mathit{high}\) | \(\small\mathbf{high}\) | \(\small\mathsf{high}\) | \(\small\mathtt{high}\) |
The argument of format_text()
is evaluated within a
math-markup. Thus math syntax such as an underscore “_” or carat “^” are
rendered in math mode, not verbatim. For example, the underscore creates
a subscript and the carat creates a superscript,
format_text("R_e")
#> [1] "$\\small\\mathrm{R_e}$"
format_text("m^3")
#> [1] "$\\small\\mathrm{m^3}$"
rendered as
To retain the underscore or carat as characters, we can try to escape the special character or use the LaTeX verbatim function,
format_text("R\\_e")
#> [1] "$\\small\\mathrm{R\\_e}$"
format_text("m\\verb|^|3")
#> [1] "$\\small\\mathrm{m\\verb|^|3}$"
rendered as
Because format_text()
is intended for columns of text in
data tables, we reproduce here a table developed in the
format_power()
vignette.
First, we’ll format the numerical columns,
# Copy to avoid "by reference" changes to air_meas
DT <- copy(air_meas)
# Format selected columns to 4 digits
cols_we_want <- c("temp", "pres", "dens")
DT <- DT[, (cols_we_want) := lapply(.SD, function(x) format_power(x, 4)), .SDcols = cols_we_want]
# Treat the gas constant with 3 digits
DT$sp_gas <- format_power(DT$sp_gas, digits = 3)
# View the result
DT[]
#> date trial humid temp pres
#> <Date> <char> <fctr> <char> <char>
#> 1: 2018-06-12 a low $\\small 294.1$ $\\small 1.011 \\times 10^{5}$
#> 2: 2018-06-13 b high $\\small 294.1$ $\\small 1.010 \\times 10^{5}$
#> 3: 2018-06-14 c med $\\small 294.6$ $\\small 1.011 \\times 10^{5}$
#> 4: 2018-06-15 d low $\\small 293.4$ $\\small 1.010 \\times 10^{5}$
#> 5: 2018-06-16 e high $\\small 293.9$ $\\small 1.011 \\times 10^{5}$
#> sp_gas dens
#> <char> <char>
#> 1: $\\small 287$ $\\small 1.198$
#> 2: $\\small 287$ $\\small 1.196$
#> 3: $\\small 287$ $\\small 1.196$
#> 4: $\\small 287$ $\\small 1.200$
#> 5: $\\small 287$ $\\small 1.199$
# Render in document
knitr::kable(DT,
align = "r",
caption = "Table 1. Numerical columns formatted; text columns unformatted.",
)
date | trial | humid | temp | pres | sp_gas | dens |
---|---|---|---|---|---|---|
2018-06-12 | a | low | \(\small 294.1\) | \(\small 1.011 \times 10^{5}\) | \(\small 287\) | \(\small 1.198\) |
2018-06-13 | b | high | \(\small 294.1\) | \(\small 1.010 \times 10^{5}\) | \(\small 287\) | \(\small 1.196\) |
2018-06-14 | c | med | \(\small 294.6\) | \(\small 1.011 \times 10^{5}\) | \(\small 287\) | \(\small 1.196\) |
2018-06-15 | d | low | \(\small 293.4\) | \(\small 1.010 \times 10^{5}\) | \(\small 287\) | \(\small 1.200\) |
2018-06-16 | e | high | \(\small 293.9\) | \(\small 1.011 \times 10^{5}\) | \(\small 287\) | \(\small 1.199\) |
Next we’ll format the three text columns using the default
face = "plain"
argument, resulting in text columns whose
typeface matches that of the numerical columns for a consistent visual
aesthetic.
# Format selected columns as text
cols_we_want <- c("date", "trial", "humid")
DT <- DT[, (cols_we_want) := lapply(.SD, function(x) format_text(x)), .SDcols = cols_we_want]
# View the result
DT[]
#> date trial humid
#> <char> <char> <char>
#> 1: $\\small\\mathrm{2018-06-12}$ $\\small\\mathrm{a}$ $\\small\\mathrm{low}$
#> 2: $\\small\\mathrm{2018-06-13}$ $\\small\\mathrm{b}$ $\\small\\mathrm{high}$
#> 3: $\\small\\mathrm{2018-06-14}$ $\\small\\mathrm{c}$ $\\small\\mathrm{med}$
#> 4: $\\small\\mathrm{2018-06-15}$ $\\small\\mathrm{d}$ $\\small\\mathrm{low}$
#> 5: $\\small\\mathrm{2018-06-16}$ $\\small\\mathrm{e}$ $\\small\\mathrm{high}$
#> temp pres sp_gas dens
#> <char> <char> <char> <char>
#> 1: $\\small 294.1$ $\\small 1.011 \\times 10^{5}$ $\\small 287$ $\\small 1.198$
#> 2: $\\small 294.1$ $\\small 1.010 \\times 10^{5}$ $\\small 287$ $\\small 1.196$
#> 3: $\\small 294.6$ $\\small 1.011 \\times 10^{5}$ $\\small 287$ $\\small 1.196$
#> 4: $\\small 293.4$ $\\small 1.010 \\times 10^{5}$ $\\small 287$ $\\small 1.200$
#> 5: $\\small 293.9$ $\\small 1.011 \\times 10^{5}$ $\\small 287$ $\\small 1.199$
# Render in document
knitr::kable(DT,
align = "r",
caption = "Table 2. Text columns formatted to match",
)
date | trial | humid | temp | pres | sp_gas | dens |
---|---|---|---|---|---|---|
\(\small\mathrm{2018-06-12}\) | \(\small\mathrm{a}\) | \(\small\mathrm{low}\) | \(\small 294.1\) | \(\small 1.011 \times 10^{5}\) | \(\small 287\) | \(\small 1.198\) |
\(\small\mathrm{2018-06-13}\) | \(\small\mathrm{b}\) | \(\small\mathrm{high}\) | \(\small 294.1\) | \(\small 1.010 \times 10^{5}\) | \(\small 287\) | \(\small 1.196\) |
\(\small\mathrm{2018-06-14}\) | \(\small\mathrm{c}\) | \(\small\mathrm{med}\) | \(\small 294.6\) | \(\small 1.011 \times 10^{5}\) | \(\small 287\) | \(\small 1.196\) |
\(\small\mathrm{2018-06-15}\) | \(\small\mathrm{d}\) | \(\small\mathrm{low}\) | \(\small 293.4\) | \(\small 1.010 \times 10^{5}\) | \(\small 287\) | \(\small 1.200\) |
\(\small\mathrm{2018-06-16}\) | \(\small\mathrm{e}\) | \(\small\mathrm{high}\) | \(\small 293.9\) | \(\small 1.011 \times 10^{5}\) | \(\small 287\) | \(\small 1.199\) |
The options()
function can be used to set global values
for two arguments in format_text()
:
face
(default is “plain”)size
(default is “small”)For example,
# Assign arguments to be used from this point forward in the script
options(
formatdown.font.size = "large",
formatdown.font.face = "italic"
)
# Copy to avoid "by reference" changes to air_meas
DT <- copy(air_meas)
# Format selected columns to 4 digits
cols_we_want <- c("temp", "pres", "dens")
DT <- DT[, (cols_we_want) := lapply(.SD, function(x) format_power(x, 4)), .SDcols = cols_we_want]
# Treat the gas constant with 3 digits
DT$sp_gas <- format_power(DT$sp_gas, digits = 3)
# Format selected columns as text
cols_we_want <- c("date", "trial", "humid")
DT <- DT[, (cols_we_want) := lapply(.SD, function(x) format_text(x)), .SDcols = cols_we_want]
# Render in document
knitr::kable(DT,
align = "r",
caption = "Table 3. Using `option()` for size size and face",
)
date | trial | humid | temp | pres | sp_gas | dens |
---|---|---|---|---|---|---|
\(\large\mathit{2018-06-12}\) | \(\large\mathit{a}\) | \(\large\mathit{low}\) | \(\large 294.1\) | \(\large 1.011 \times 10^{5}\) | \(\large 287\) | \(\large 1.198\) |
\(\large\mathit{2018-06-13}\) | \(\large\mathit{b}\) | \(\large\mathit{high}\) | \(\large 294.1\) | \(\large 1.010 \times 10^{5}\) | \(\large 287\) | \(\large 1.196\) |
\(\large\mathit{2018-06-14}\) | \(\large\mathit{c}\) | \(\large\mathit{med}\) | \(\large 294.6\) | \(\large 1.011 \times 10^{5}\) | \(\large 287\) | \(\large 1.196\) |
\(\large\mathit{2018-06-15}\) | \(\large\mathit{d}\) | \(\large\mathit{low}\) | \(\large 293.4\) | \(\large 1.010 \times 10^{5}\) | \(\large 287\) | \(\large 1.200\) |
\(\large\mathit{2018-06-16}\) | \(\large\mathit{e}\) | \(\large\mathit{high}\) | \(\large 293.9\) | \(\large 1.011 \times 10^{5}\) | \(\large 287\) | \(\large 1.199\) |
You can overwrite your global assignment using the face
or size
argument in any individual function call.
face
option affects arguments of
format_text()
only.size
option affects arguments of both
format_text()
and format_power()
.