---
title: "Format integers and decimals"
output: rmarkdown::html_vignette
vignette: >
  %\VignetteIndexEntry{Format integers and decimals}
  %\VignetteEngine{knitr::rmarkdown}
  %\VignetteEncoding{UTF-8}
---

```{r setup, include = FALSE}
knitr::opts_chunk$set(
  collapse = TRUE,
  comment = "#>"
)

options(
  datatable.print.nrows = 15,
  datatable.print.topn = 3,
  datatable.print.class = TRUE
)
```


![](../man/figures/real-number-line.png){width=70%}    
<small>*Real number line* by <a href="https://commons.wikimedia.org/wiki/File:Real_number_line.svg">User:Phrood~commonswiki</a>, Public domain, via Wikimedia Commons</small>

<br>


If we use `format_power()` to create powers-of-ten notation in a table, the  font face and size of these values do not necessarily match that of unformatted numbers. 

The purpose of `format_decimal()` is to surround decimal numbers and integers with inline math delimiters to match the powers-of-ten font face and size in rendering an R Markdown or Quarto Markdown output document. 







## `format_decimal()`

Given a number, a numerical vector, or a numerical column from a data frame, `format_decimal()` converts the numbers to character strings of the form, 

        "$a$" 
 
The user can specify the number of decimal places. 

*Arguments.*

- **x** &nbsp; Numerical vector to be formatted. Can be a scalar, a vector, or a column from a data frame. 

- **digits** &nbsp; Positive integer to specify the number of decimal places.  Default is 4. Zero renders the number as an integer. 

- **big_mark** &nbsp; Character. If not empty, used as mark between every three digits before the decimal point. Applied as the `big.mark` argument of `formatC()`.

- **delim** &nbsp; Character vector of length one or two defining the math markup delimiters. Possible values include `"$"` 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:

```{r}
library("formatdown")
library("data.table")
library("knitr")
```






## Practice data table

Using the `atmos` data set include with `formatdown` with various atmospheric properties as a function of height above sea level. 

```{r}
# Data set included with formatdown
DT <- copy(atmos)

# Render in document
knitr::kable(DT, align = "r")
```




## Power-of-ten column 

Of these variables, density best lends itself to powers-of-ten notation. For this range of values, a fixed exponent of $-3$ seems to work OK. 

```{r}
# Apply power of ten notation to one column
DT$dens <- format_power(DT$dens, digits = 3, set_power = -3)

# Render in document
knitr::kable(DT, align = "r")
```






## Integer column

I treat the altitude as an integer, convert from meters to kilometers, and format in integer form (zero decimal places). 

```{r}
# Format one column as an integer
DT$alt <- format_decimal(DT$alt / 1000, 0)

# Render in document
knitr::kable(DT, align = "r")
```







## Decimal columns

The temperature and speed of sound columns can both be formatted to one decimal place. Use `lapply()` to format multiple columns in the same way. 

```{r}
# Name the columns to be formatted
cols_to_format <- c("temp", "sound")

# Use data.table .SD syntax with lapply()
DT[, (cols_to_format) := lapply(.SD, function(x) format_decimal(x, 1)), .SDcols = cols_to_format]

# Render in document
knitr::kable(DT, align = "r")
```






## Different formats in different ranges

The pressure column spans several orders of magnitude. I format these numbers differently depending on the range they occupy. For numbers in the thousands, I add a "big mark" to make them easier to read. 

```{r}
# Hundreds and higher, integers. Create a temporary variable
DT[pres > 99, temp_pres := format_decimal(pres, 0, big_mark = ",")]

# Units place or lower, 2 decimal places
DT[pres <= 10, temp_pres := format_decimal(pres, 2)]

# In-between those two ranges, 1 decimal place
DT[pres > 10 & pres <= 99, temp_pres := format_decimal(pres, 1)]

# Overwrite the original and delete the temporary column
DT[, pres := temp_pres]
DT[, temp_pres := NULL]

# Render in document
knitr::kable(DT, align = "r")
```






## `knitr::kable()` options

I use some `knitr::kable()` arguments to change the header and add a caption. 


```{r}
# Render in document
knitr::kable(DT,
  align = "r",
  caption = "Table 1. Atmospheric varables as a function of altitude",
  col.names = c(
    "Altitude [km]",
    "Temperature [K]",
    "Pressure [Pa]",
    "Density [kg/m$^3$]",
    "Speed of sound [m/s]"
  )
)
```







