The unit_conversion() function

Let’s use a portion of the towny dataset and create a table showing population, density, and land area for 10 municipalities. The land_area_km2 values are in units of square kilometers, however, we’d rather the values were in square miles. We can convert the numeric values while formatting the values with fmt_number() by using unit_conversion() in the scale_by argument since the return value of that is a conversion factor (which is applied to each value by multiplication). The same is done for converting the ‘people per square kilometer’ values in density_2021 to ‘people per square mile’, however, the units to convert are in the denominator so the inverse of the conversion factor must be used.

towny |>
  dplyr::arrange(desc(density_2021)) |>
  dplyr::slice_head(n = 10) |>
  dplyr::select(name, population_2021, density_2021, land_area_km2) |>
  gt(rowname_col = "name") |>
  fmt_integer(columns = population_2021) |>
  fmt_number(
    columns = land_area_km2,
    decimals = 1,
    scale_by = unit_conversion(
      from = "area.square-kilometer",
      to = "area.square-mile"
    )
  ) |>
  fmt_number(
    columns = density_2021,
    decimals = 1,
    scale_by = 1 / unit_conversion(
      from = "area.square-kilometer",
      to = "area.square-mile"
    )
  ) |>
  cols_label(
    land_area_km2 = "Land Area,<br>sq. mi",
    population_2021 = "Population",
    density_2021 = "Density,<br>ppl / sq. mi",
    .fn = md
  )
Population Density,
ppl / sq. mi
Land Area,
sq. mi
Toronto 2,794,356 11,467.8 243.7
Brampton 656,480 6,394.7 102.7
Mississauga 717,961 6,352.1 113.0
Newmarket 87,942 5,916.1 14.9
Richmond Hill 202,022 5,191.3 38.9
Orangeville 30,167 5,153.8 5.9
Ajax 126,666 4,922.9 25.7
Waterloo 121,436 4,909.7 24.7
Kitchener 256,885 4,863.2 52.8
Guelph 143,740 4,258.1 33.8

With a small slice of the gibraltar dataset, let’s display the temperature values in terms of degrees Celsius (present in the data) and as temperatures in degrees Fahrenheit (achievable via conversion). We can duplicate the temp column through cols_add() (naming the new column as temp_f) and when formatting through fmt_integer() we can call unit_conversion() within the scale_by argument to perform this transformation while formatting the values as integers.

gibraltar |>
  dplyr::filter(
    date == "2023-05-15",
    time >= "06:00",
    time <= "12:00"
  ) |>
  dplyr::select(time, temp) |>
  gt() |>
  tab_header(
    title = "Air Temperature During Late Morning Hours at LXGB Stn.",
    subtitle = "May 15, 2023"
  ) |>
  cols_add(temp_f = temp) |>
  cols_move(columns = temp_f, after = temp) |>
  tab_spanner(
    label = "Temperature",
    columns = starts_with("temp")
  ) |>
  fmt_number(
    columns = temp,
    decimals = 1
  ) |>
  fmt_integer(
    columns = temp_f,
    scale_by = unit_conversion(
      from = "temperature.C",
      to = "temperature.F"
    )
  ) |>
  cols_label(
    time = "Time",
    temp = "{{degC}}",
    temp_f = "{{degF}}"
  ) |>
  cols_width(
    starts_with("temp") ~ px(80),
    time ~ px(100)
  ) |>
  opt_horizontal_padding(scale = 3) |>
  opt_vertical_padding(scale = 0.5) |>
  opt_align_table_header(align = "left") |>
  tab_options(heading.title.font.size = px(16))
Air Temperature During Late Morning Hours at LXGB Stn.
May 15, 2023
Time
Temperature
°C °F
06:50 18.9 66
07:50 18.9 66
08:50 20.0 68
09:20 20.0 68
09:50 20.0 68
10:20 21.1 70
10:50 22.2 72
11:20 22.2 72
11:50 22.8 73