The fmt_number() function

Let’s use the exibble dataset to create a gt table. With fmt_number(), we’ll format the num column to have three decimal places (with decimals = 3) and omit the use of digit separators (with use_seps = FALSE).

exibble |>
  gt() |>
  fmt_number(
    columns = num,
    decimals = 3,
    use_seps = FALSE
  )
num char fctr date time datetime currency row group
0.111 apricot one 2015-01-15 13:35 2018-01-01 02:22 49.950 row_1 grp_a
2.222 banana two 2015-02-15 14:40 2018-02-02 14:33 17.950 row_2 grp_a
33.330 coconut three 2015-03-15 15:45 2018-03-03 03:44 1.390 row_3 grp_a
444.400 durian four 2015-04-15 16:50 2018-04-04 15:55 65100.000 row_4 grp_a
5550.000 NA five 2015-05-15 17:55 2018-05-05 04:00 1325.810 row_5 grp_b
NA fig six 2015-06-15 NA 2018-06-06 16:11 13.255 row_6 grp_b
777000.000 grapefruit seven NA 19:10 2018-07-07 05:22 NA row_7 grp_b
8880000.000 honeydew eight 2015-08-15 20:20 NA 0.440 row_8 grp_b

Use a modified version of the countrypops dataset to create a gt table with row labels. Format all columns to use large-number suffixing (e.g., where "10,000,000" becomes "10M") with the suffixing = TRUE option.

countrypops |>
  dplyr::select(country_code_3, year, population) |>
  dplyr::filter(country_code_3 %in% c("CHN", "IND", "USA", "PAK", "IDN")) |>
  dplyr::filter(year > 1975 & year %% 5 == 0) |>
  tidyr::spread(year, population) |>
  dplyr::arrange(desc(`2015`)) |>
  gt(rowname_col = "country_code_3") |>
  fmt_number(suffixing = TRUE)
1980 1985 1990 1995 2000 2005 2010 2015 2020
CHN 981.23M 1.05B 1.14B 1.20B 1.26B 1.30B 1.34B 1.38B 1.41B
IND 696.83M 780.24M 870.45M 964.28M 1.06B 1.15B 1.24B 1.32B 1.40B
USA 227.22M 237.92M 249.62M 266.28M 282.16M 295.52M 309.33M 320.74M 331.51M
IDN 148.18M 165.79M 182.16M 198.14M 214.07M 228.81M 244.02M 259.09M 271.86M
PAK 80.62M 97.12M 115.41M 133.12M 154.37M 174.37M 194.45M 210.97M 227.20M

In a variation of the previous table, we can combine large-number suffixing with a declaration of the number of significant digits to use. With things like population figures, n_sigfig = 3 is a very good option.

countrypops |>
  dplyr::select(country_code_3, year, population) |>
  dplyr::filter(country_code_3 %in% c("CHN", "IND", "USA", "PAK", "IDN")) |>
  dplyr::filter(year > 1975 & year %% 5 == 0) |>
  tidyr::spread(year, population) |>
  dplyr::arrange(desc(`2015`)) |>
  gt(rowname_col = "country_code_3") |>
  fmt_number(suffixing = TRUE, n_sigfig = 3)
1980 1985 1990 1995 2000 2005 2010 2015 2020
CHN 981M 1.05B 1.14B 1.20B 1.26B 1.30B 1.34B 1.38B 1.41B
IND 697M 780M 870M 964M 1.06B 1.15B 1.24B 1.32B 1.40B
USA 227M 238M 250M 266M 282M 296M 309M 321M 332M
IDN 148M 166M 182M 198M 214M 229M 244M 259M 272M
PAK 80.6M 97.1M 115M 133M 154M 174M 194M 211M 227M

There can be cases where you want to show numbers to a large number of decimal places but also drop the unnecessary trailing zeros for low-precision values. Let’s take a portion of the towny dataset and format the latitude and longitude columns with fmt_number(). We’ll have up to 5 digits displayed as decimal values, but we’ll also unconditionally drop any runs of trailing zeros in the decimal part with drop_trailing_zeros = TRUE.

towny |>
  dplyr::select(name, latitude, longitude) |>
  dplyr::slice_head(n = 10) |>
  gt() |>
  fmt_number(decimals = 5, drop_trailing_zeros = TRUE) |>
  cols_merge(columns = -name, pattern = "{1}, {2}") |>
  cols_label(
    name ~ "Municipality",
    latitude = "Location"
  )
Municipality Location
Addington Highlands 45, −77.25
Adelaide Metcalfe 42.95, −81.7
Adjala-Tosorontio 44.13333, −79.93333
Admaston/Bromley 45.52917, −76.89694
Ajax 43.85833, −79.03639
Alberton 48.6, −93.53333
Alfred and Plantagenet 45.56667, −74.91667
Algonquin Highlands 45.4, −78.75
Alnwick/Haldimand 44.08333, −78.03333
Amaranth 43.98333, −80.23333

Another strategy for dealing with precision of decimals is to have a separate column of values that specify how many decimal digits to retain. Such a column can be added via cols_add() or it can be part of the input table for gt(). With that column available, it can be referenced in the decimals argument with from_column(). This approach yields a display of coordinate values that reflects the measurement precision of each value.

towny |>
  dplyr::select(name, latitude, longitude) |>
  dplyr::slice_head(n = 10) |>
  gt() |>
  cols_add(dec_digits = c(1, 2, 2, 5, 5, 2, 3, 2, 3, 3)) |>
  fmt_number(decimals = from_column(column = "dec_digits")) |>
  cols_merge(columns = -name, pattern = "{1}, {2}") |>
  cols_label(
    name ~ "Municipality",
    latitude = "Location"
  )
Municipality Location
Addington Highlands 45.0, −77.2
Adelaide Metcalfe 42.95, −81.70
Adjala-Tosorontio 44.13, −79.93
Admaston/Bromley 45.52917, −76.89694
Ajax 43.85833, −79.03639
Alberton 48.60, −93.53
Alfred and Plantagenet 45.567, −74.917
Algonquin Highlands 45.40, −78.75
Alnwick/Haldimand 44.083, −78.033
Amaranth 43.983, −80.233