Global settings


option by Mike Lawrence is licensed under CC BY 2.0 DEED https://creativecommons.org/licenses/by/2.0/.


Global options are provided for arguments that users are likely prefer to set once in a document instead of repeating in every function call. For example, some users prefer a comma decimal marker (“,”) throughout a document.

Globally-set arguments can be overridden locally by assigning them in a function call.

formatdown_options()

Set, examine, or reset several global options which affect the way in which a formatted object is rendered in an R markdown document. The options and their default settings are

formatdown_options(delim = "$",
                   size = NULL,
                   decimal_mark = ".",
                   big_mark = "",
                   big_interval = 3,
                   small_mark = "",
                   small_interval = 5,
                   whitespace = "\\\\>", 
                   reset = FALSE)

To reset all formatdown arguments to their default values:

    formatdown_options(reset = TRUE)


Usage.   For example, get two of the current settings.

formatdown_options("size", "decimal_mark")
#> $size
#> NULL
#> 
#> $decimal_mark
#> [1] "."

Assign new settings; examine result.

# Set
formatdown_options(size = "large", decimal_mark = ",")

# Examine result
formatdown_options("size", "decimal_mark")
#> $size
#> [1] "large"
#> 
#> $decimal_mark
#> [1] ","

Reset to default values; examine result.

# Set to defaults
formatdown_options(reset = TRUE)

# Examine result
formatdown_options("size", "decimal_mark")
#> $size
#> NULL
#> 
#> $decimal_mark
#> [1] "."

Delimiters

Delimiters are characters that surround a formatted expression such that R Markdown renders it as an inline math expression.

Sometimes the default $ ... $ delimiters fail to render correctly. I encountered this once using kableExtra::kbl() in a .qmd document. The solution, suggested by the MathJax consortium (Cervone, 2018), is to use the delimiter pair \( ... \), hence the built-in alternate, delim = "\\(".

Left and right custom delimiters can be assigned in a vector, e.g., c("\\[", "\\]").


Examples.   Note that using format_text() introduces additional markup inside the delimiters. Details are described in the Format text article.

x <- 101300
txt <- "Hello world!"

# 1. Numeric input, default delimiters
format_dcml(x)
#> [1] "$101300$"

# 2. Numeric input, alternate delimiters
format_dcml(x, delim = "\\(")
#> [1] "\\(101300\\)"

# 3. Character input, default delimiters
format_text(txt)
#> [1] "$\\mathrm{Hello\\>world!}$"

# 4. Character input, alternate delimiters
format_text(txt, delim = "\\(")
#> [1] "\\(\\mathrm{Hello\\>world!}\\)"


Examples 1–4 (in inline code chunks) render as,

  1. \(\small 101300\)

  2. \(\small 101300\)

  3. \(\small \mathrm{Hello\>world!}\)

  4. \(\small \mathrm{Hello\>world!}\)


Font size

Font size is set using LaTeX-style macros inside the math-delimited expression. For example, with size = "small" (or size = "\\small"), the formatdown markup of the Avogadro constant would be

    "$\\small 6.0221 \\times 10^{23}$", 

where the extra backslashes are necessary to escape the backslashes in \small and \times. If size = NULL (default), no size command is added and the font size is equivalent to "normalsize".


Examples.

# 5. Numeric input
format_dcml(x, size = "scriptsize")
#> [1] "$\\scriptsize 101300$"

# 6. Numeric input
format_dcml(x, size = "small")
#> [1] "$\\small 101300$"

# 7. Power-of-ten number using LaTeX-style size markup
format_sci(6.0221e+23, size = "\\small")
#> [1] "$\\small 6.022 \\times 10^{23}$"

# 8. Character input, default size
format_text(txt)
#> [1] "$\\mathrm{Hello\\>world!}$"

# 9. Character input
format_text(txt, size = "large")
#> [1] "$\\large \\mathrm{Hello\\>world!}$"


Examples 5–9 render as,

  1. \(\scriptsize 101300\)

  2. \(\small 101300\)

  3. \(\small 6.022 \times 10^{23}\)

  4. \(\mathrm{Hello\>world!}\)

  5. \(\large \mathrm{Hello\>world!}\)


Available sizes

Comparing decimal notation, scientific notation, and text in possible font sizes (formatdown does not support the sizes: tiny, footnotesize, Large, LARGE, and Huge).

scriptsize small normalsize large huge
\(\scriptsize 3.1416\) \(\small 3.1416\) \(\normalsize 3.1416\) \(\large 3.1416\) \(\huge 3.1416\)
\(\scriptsize 5 \times 10^{3}\) \(\small 5 \times 10^{3}\) \(\normalsize 5 \times 10^{3}\) \(\large 5 \times 10^{3}\) \(\huge 5 \times 10^{3}\)
\(\scriptsize \mathrm{The\>cat}\) \(\small \mathrm{The\>cat}\) \(\normalsize \mathrm{The\>cat}\) \(\large \mathrm{The\>cat}\) \(\huge \mathrm{The\>cat}\)

Decimal separator

For a number written in decimal form, the decimal mark separates the integer part from the fractional part.

The decimal mark in formatdown may be reset locally in a function call or globally using formatdown_options(); it is not affected by the base R option OutDec.


Examples.

# 10. Decimal markup
x <- pi
format_dcml(x, 5, decimal_mark = ",")
#> [1] "$3,1416$"

# 11. Power-of-ten markup
y <- 1.602176634e-19
format_sci(y, 5, decimal_mark = ",")
#> [1] "$1,6022 \\times 10^{-19}$"


Examples 10 and 11 render as,

  1. \(\small 3,1416\)

  2. \(\small 1,6022 \times 10^{-19}\)


Separating digits

The NIST recommends we use a thin space to separate more than 4 digits to the left or to the right of a decimal marker (Thompson & Taylor, 2022, p. 10.5.3):

… digits should be separated into groups of three, counting from the decimal marker towards the left and right, by the use of a thin, fixed space. However, this practice is not usually followed for numbers having only four digits on either side of the decimal marker except when uniformity in a table is desired.

Both big_mark and small_mark add the horizontal-space characters inside the math delimiters; big_mark to the integer portion and small_mark to the fractional portion. The possible values are empty "" (default), "thin", or the thin-space macro itself \\\\,.

The interval arguments big_interval and small_interval set the number of digits separated by thin spaces when big_mark or small_mark are not empty. However, formatdown does not encode the exemption for 4-digit groups mentioned in the NIST quote above.


Examples.

w <- 1013
x <- 101300
y <- 0.002456
z <- x + y

# 12. 4-digit number, no space
format_dcml(w)
#> [1] "$1013$"

# 13. 4-digit number, with space
format_dcml(w, big_mark = "thin")
#> [1] "$1\\,013$"

# 14. Group digits to the left of the decimal
format_dcml(x, big_mark = "thin")
#> [1] "$101\\,300$"

# 15. Group digits to the right of the decimal
format_dcml(y, small_mark = "\\\\,")
#> [1] "$0.00245\\,6$"

# 16. Change the small interval
format_dcml(y, small_mark = "\\\\,", small_interval = 3)
#> [1] "$0.002\\,456$"

# 17. Group digits to the left and right of the decimal
format_dcml(z, 12, big_mark = "thin", small_mark = "thin")
#> [1] "$101\\,300.00245\\,6$"


Examples 12–17 render as,

  1. \(\small 1013\)

  2. \(\small 1\,013\)

  3. \(\small 101\,300\)

  4. \(\small 0.00245\,6\)

  5. \(\small 0.002\,456\)

  6. \(\small 101\,300.00245\,6\)

Preserving text spaces

The horizontal-space macro is used to preserve spaces in text formatted with format_text() as well as spaces within physical-unit strings with format_numbers(). Without it, an inline math markup such as

    $\mathrm{This Is Math Text.}$

is rendered in an R markdown document as

\(\qquad\) \(\small\mathrm{This Is Math Text.}\)

To preserve such spaces, formatdown substitutes the character string \> for each space, producing output like the following, where backslashes have been escaped,

    "$\\mathrm{This\\>Is\\>Math\\>Text.}$"

rendered as,

\(\qquad\) \(\small\mathrm{This\>Is\>Math\>Text.}\)

Because the backslashes must be escaped, the formatdown output is \(\small\mathtt{\verb|"\\>"|}\), but the the argument value set by the user is whitespace = \(\small\mathtt{\verb|"\\\\>"|}\). One may also use \(\mathtt{\small\verb|"\\\\:"|}\) or \(\mathtt{\small\verb|"\\\\ "|}\).


Examples.

# 18. Character input, default space '\>'
format_text(txt, whitespace = "\\\\>")
#> [1] "$\\mathrm{Hello\\>world!}$"

# 19. Character input, alternate space '\:'
format_text(txt, whitespace = "\\\\:")
#> [1] "$\\mathrm{Hello\\:world!}$"

# 20. Character input, alternate space '\ '
format_text(txt, whitespace = "\\\\ ")
#> [1] "$\\mathrm{Hello\\ world!}$"


Examples 18–20 render as,

  1. \(\small \mathrm{Hello\>world!}\)

  2. \(\small \mathrm{Hello\:world!}\)

  3. \(\small \mathrm{Hello\ world!}\)

Applications

Example 21.

In this example, we format different columns of a data frame using decimal_mark, big_mark and small_mark.

# Set options
formatdown_options(decimal_mark = ",", big_mark = "thin", small_mark = "thin")

# Use water data included with formatdown
DT <- copy(water)[1:6]

# Examine the data frame
DT[]
#>      temp   dens   sp_wt       visc bulk_mod
#>     <num>  <num>   <num>      <num>    <num>
#> 1: 273.15 999.87 9808.70 0.00173360 2.02e+09
#> 2: 283.15 999.73 9807.33 0.00131050 2.10e+09
#> 3: 293.15 998.23 9792.67 0.00102120 2.18e+09
#> 4: 303.15 995.68 9767.60 0.00081743 2.25e+09
#> 5: 313.15 992.25 9733.95 0.00066988 2.28e+09
#> 6: 323.15 988.06 9692.90 0.00056046 2.29e+09

# Routine decimal formatting
DT$temp <- format_dcml(DT$temp)
DT$dens <- format_dcml(DT$dens)

# Omit big_mark spacing for 4 digits
DT$sp_wt <- format_dcml(DT$sp_wt, 4, big_mark = "")

# Set significant digits (viscosity) to achieve a consistent string length
DT[visc >= 0.001, temp_visc := format_dcml(visc, 5)]
DT[visc < 0.001, temp_visc := format_dcml(visc, 4)]
DT[, visc := temp_visc]
DT[, temp_visc := NULL]

# Will appear with big_mark spacing, change from Pa to kPa
DT$bulk_mod_kPa <- format_dcml(DT$bulk_mod/1000, 4)
DT$bulk_mod <- NULL

knitr::kable(DT, align = "r", caption = "Example 21.")
Example 21.
temp dens sp_wt visc bulk_mod_kPa
\(\small 273,2\) \(\small 999,9\) \(\small 9809\) \(\small 0,00173\,36\) \(\small 2\,020\,000\)
\(\small 283,2\) \(\small 999,7\) \(\small 9807\) \(\small 0,00131\,05\) \(\small 2\,100\,000\)
\(\small 293,2\) \(\small 998,2\) \(\small 9793\) \(\small 0,00102\,12\) \(\small 2\,180\,000\)
\(\small 303,2\) \(\small 995,7\) \(\small 9768\) \(\small 0,00081\,74\) \(\small 2\,250\,000\)
\(\small 313,2\) \(\small 992,2\) \(\small 9734\) \(\small 0,00066\,99\) \(\small 2\,280\,000\)
\(\small 323,2\) \(\small 988,1\) \(\small 9693\) \(\small 0,00056\,05\) \(\small 2\,290\,000\)

# Set package options to default values
formatdown_options(reset = TRUE)


Example 22.

Same table, but using power of ten formatting.

# Use water data included with formatdown
DT <- copy(water)[1:6]

# Routine decimal formatting
cols <- c("temp", "dens", "sp_wt")
DT[, (cols) := lapply(.SD, function(x) format_dcml(x)), .SDcols = cols]

# Power of ten
DT$bulk_mod <- format_engr(DT$bulk_mod, 3)
DT$visc <- format_engr(DT$visc, 4, set_power = -3)

knitr::kable(DT, align = "r", caption = "Example 22.")
Example 22.
temp dens sp_wt visc bulk_mod
\(\small 273.2\) \(\small 999.9\) \(\small 9809\) \(\small 1.734 \times 10^{-3}\) \(\small 2.02 \times 10^{9}\)
\(\small 283.2\) \(\small 999.7\) \(\small 9807\) \(\small 1.310 \times 10^{-3}\) \(\small 2.10 \times 10^{9}\)
\(\small 293.2\) \(\small 998.2\) \(\small 9793\) \(\small 1.021 \times 10^{-3}\) \(\small 2.18 \times 10^{9}\)
\(\small 303.2\) \(\small 995.7\) \(\small 9768\) \(\small 0.8174 \times 10^{-3}\) \(\small 2.25 \times 10^{9}\)
\(\small 313.2\) \(\small 992.2\) \(\small 9734\) \(\small 0.6699 \times 10^{-3}\) \(\small 2.28 \times 10^{9}\)
\(\small 323.2\) \(\small 988.1\) \(\small 9693\) \(\small 0.5605 \times 10^{-3}\) \(\small 2.29 \times 10^{9}\)


Example 23.

The metals data set includes columns of text and decimal and power-of-ten numbers.

# Use water data included with formatdown
DT <- copy(metals)

# Examine the data frame
DT[]
#>            metal  dens  thrm_exp thrm_cond  elast_mod
#>           <char> <num>     <num>     <num>      <num>
#> 1: aluminum 6061  2700 2.430e-05    155.77 7.3084e+10
#> 2:        copper  8900 1.656e-05    392.88 1.1721e+11
#> 3:          lead 11340 5.274e-05     37.04 1.3790e+10
#> 4:      platinum 21450 9.000e-06     69.23 1.4686e+11
#> 5:    steel 1020  7850 1.134e-05     46.73 2.0684e+11
#> 6:      titanium  4850 9.360e-06      7.44 1.0204e+11

# Text
DT$metal <- format_text(DT$metal)

# Decimal
cols <- c("dens", "thrm_cond")
DT[, (cols) := lapply(.SD, function(x) format_dcml(x)), .SDcols = cols]

# Power of ten
cols <- c("elast_mod", "thrm_exp")
DT[, (cols) := lapply(.SD, function(x) format_engr(x, 3)), .SDcols = cols]

knitr::kable(DT, align = "lrrrr", caption = "Example 23.")
Example 23.
metal dens thrm_exp thrm_cond elast_mod
\(\small \mathrm{aluminum\>6061}\) \(\small 2700\) \(\small 24.3 \times 10^{-6}\) \(\small 155.8\) \(\small 73.1 \times 10^{9}\)
\(\small \mathrm{copper}\) \(\small 8900\) \(\small 16.6 \times 10^{-6}\) \(\small 392.9\) \(\small 117 \times 10^{9}\)
\(\small \mathrm{lead}\) \(\small 11340\) \(\small 52.7 \times 10^{-6}\) \(\small 37.04\) \(\small 13.8 \times 10^{9}\)
\(\small \mathrm{platinum}\) \(\small 21450\) \(\small 9.00 \times 10^{-6}\) \(\small 69.23\) \(\small 147 \times 10^{9}\)
\(\small \mathrm{steel\>1020}\) \(\small 7850\) \(\small 11.3 \times 10^{-6}\) \(\small 46.73\) \(\small 207 \times 10^{9}\)
\(\small \mathrm{titanium}\) \(\small 4850\) \(\small 9.36 \times 10^{-6}\) \(\small 7.440\) \(\small 102 \times 10^{9}\)

References

Cervone, D. (2018). MathJax: TeX and LaTeX math delimiters. https://docs.mathjax.org/en/v2.7-latest/tex.html#tex-and-latex-math-delimiters
Thompson, A., & Taylor, B. N. (2022). NIST Guide to the SI, Chapter 10: More on Printing and Using Symbols and Numbers in Scientific and Technical Documents. US National Institute of Standards and Technology. https://www.nist.gov/pml/special-publication-811/nist-guide-si-chapter-10-more-printing-and-using-symbols-and-numbers