Format text


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.

Markup

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.

If you are writing your own script to follow along, we use these packages in this vignette:

library("formatdown")
library("data.table")
library("knitr")



options(formatdown.font.size = "small")

Font size

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}\)

Typeface

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}\)

Special characters in math mode

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

Tables of data

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.",
)
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",
)
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\)

Options

The options() function can be used to set global values for two arguments in format_text():

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",
)
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.