Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unit conversion helper #1704

Merged
merged 26 commits into from
Jun 14, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
d14d4ad
Create conversion_factors.csv
rich-iannone Jun 12, 2024
d061957
Create X15-conversion_factors.R
rich-iannone Jun 13, 2024
c0bc96d
Update zz_process_datasets_ext.R
rich-iannone Jun 13, 2024
3ad6ec8
Drop spec() attribute from many internal datasets
rich-iannone Jun 13, 2024
497f63f
Update sysdata.rda
rich-iannone Jun 13, 2024
422e10b
Make correction to CSV data
rich-iannone Jun 13, 2024
c295a03
Update sysdata.rda
rich-iannone Jun 13, 2024
3beeb44
Add the `unit_conversion()` helper
rich-iannone Jun 13, 2024
178ed9c
Update NAMESPACE
rich-iannone Jun 13, 2024
4f1ab62
Create unit_conversion.Rd
rich-iannone Jun 13, 2024
9a25be4
Update help files using roxygen
rich-iannone Jun 13, 2024
cfe5d96
Create man_unit_conversion_1.png
rich-iannone Jun 14, 2024
babadfc
Add example to `unit_conversion()`
rich-iannone Jun 14, 2024
8d91cbf
Update unit_conversion.Rd
rich-iannone Jun 14, 2024
bb1200e
Update _pkgdown.yml
rich-iannone Jun 14, 2024
7ad67c8
Update zzz-build_info_tables.R
rich-iannone Jun 14, 2024
a06e64e
Create info_conversions.rds
rich-iannone Jun 14, 2024
5c303fa
Create man_info_unit_conversions_1.png
rich-iannone Jun 14, 2024
8773769
Adjust error messages
rich-iannone Jun 14, 2024
e28570f
Add comment
rich-iannone Jun 14, 2024
6e3f5a2
Add reference to associated info table
rich-iannone Jun 14, 2024
c8f4567
Create info table function
rich-iannone Jun 14, 2024
d7c3afd
Update NAMESPACE
rich-iannone Jun 14, 2024
001221d
Update _pkgdown.yml
rich-iannone Jun 14, 2024
a254da4
Create info_unit_conversions.Rd
rich-iannone Jun 14, 2024
0965e59
Update help files using roxygen
rich-iannone Jun 14, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions NAMESPACE
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,7 @@ export(info_icons)
export(info_locales)
export(info_paletteer)
export(info_time_style)
export(info_unit_conversions)
export(local_image)
export(matches)
export(md)
Expand Down Expand Up @@ -218,6 +219,7 @@ export(text_case_match)
export(text_case_when)
export(text_replace)
export(text_transform)
export(unit_conversion)
export(vars)
export(vec_fmt_bytes)
export(vec_fmt_currency)
Expand Down
123 changes: 121 additions & 2 deletions R/helpers.R
Original file line number Diff line number Diff line change
Expand Up @@ -524,6 +524,125 @@ currency <- function(
currency_list
}

#' Get a conversion factor across two measurement units of a given class
#'
#' @description
#'
#' The `unit_conversion()` helper function gives us a conversion factor for
#' transforming a value from one form of measurement units to a target form.
#' For example if you have a length value that is expressed in miles you could
#' transform that value to one in kilometers through multiplication of the value
#' by the conversion factor (in this case `1.60934`).
#'
#' For `unit_conversion()` to understand the source and destination units, you
#' need to provide a keyword value for the `from` and `to` arguments. To aid as
#' a reference for this, call [info_unit_conversions()] to display an
#' information table that contains all of the keywords for every conversion
#' type.
#'
#' @param from *Units for the input value*
#'
#' `scalar<character>` // **required**
#'
#' The keyword representing the units for the value that requires unit
#' conversion. In the case where the value has units of miles, the necessary
#' input is `"length.mile"`.
#'
#' @param to *Desired units for the value*
#'
#' `scalar<character>` // **required**
#'
#' The keyword representing the target units for the value with units defined
#' in `from`. In the case where input value has units of miles and we would
#' rather want the value to be expressed as kilometers, the `to` value should
#' be `"length.kilometer"`.
#'
#' @return A single numerical value.
#'
#' @section Examples:
#'
#' 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.
#'
#' ```r
#' 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
#' )
#' ```
#'
#' \if{html}{\out{
#' `r man_get_image_tag(file = "man_unit_conversion_1.png")`
#' }}
#'
#' @family helper functions
#' @section Function ID:
#' 8-7
#'
#' @section Function Introduced:
#' *In Development*
#'
#' @export
unit_conversion <- function(from, to) {

force(from)
force(to)

if (!(from %in% conversion_factors[["from"]])) {
cli::cli_abort("The unit supplied in {.arg from} is not known.")
}
if (!(to %in% conversion_factors[["to"]])) {
cli::cli_abort("The unit supplied in {.arg to} is not known.")
}

if (from == to) {
return(1.0)
}

row_conversion <-
dplyr::filter(conversion_factors, from == {{ from }}, to == {{ to }})

# In the case where units are valid and available in the internal dataset,
# they may be across categories; such pairings do not allow for a conversion
# to take place
if (nrow(row_conversion) < 1) {
cli::cli_abort("The conversion specified cannot be performed.")
}

row_conversion[["conv_factor"]]
}

#' Supply nanoplot options to `cols_nanoplot()`
#'
Expand Down Expand Up @@ -778,7 +897,7 @@ currency <- function(
#'
#' @family helper functions
#' @section Function ID:
#' 8-7
#' 8-8
#'
#' @section Function Introduced:
#' `v0.10.0` (October 7, 2023)
Expand Down Expand Up @@ -984,7 +1103,7 @@ nanoplot_options <- function(
#'
#' @family helper functions
#' @section Function ID:
#' 8-8
#' 8-9
#'
#' @section Function Introduced:
#' `v0.2.0.5` (March 31, 2020)
Expand Down
38 changes: 38 additions & 0 deletions R/info_tables.R
Original file line number Diff line number Diff line change
Expand Up @@ -824,3 +824,41 @@ info_flags <- function() {
info_icons <- function() {
readRDS(system_file("gt_tables/info_icons.rds"))
}

#' View a table with all units that can be converted by `unit_conversion()`
#'
#' @description
#'
#' [unit_conversion()] can be used to yield conversion factors across compatible
#' pairs of units. This is useful for expressing values in different units and
#' the conversion can be performed via the `scale_by` argument available in
#' several formatting functions. When calling [unit_conversion()], one must
#' supply two string-based keywords to specify the value's current units and the
#' desired units. All of these keywords are provided in the table shown by
#' calling `info_unit_conversions()`.
#'
#' @return An object of class `gt_tbl`.
#'
#' @section Examples:
#'
#' Get a table of info on all the available keywords for unit conversions.
#'
#' ```r
#' info_unit_conversions()
#' ```
#'
#' \if{html}{\out{
#' `r man_get_image_tag(file = "man_info_unit_conversions_1.png")`
#' }}
#'
#' @family information functions
#' @section Function ID:
#' 11-9
#'
#' @section Function Introduced:
#' *In Development*
#'
#' @export
info_unit_conversions <- function() {
readRDS(system_file("gt_tables/info_conversions.rds"))
}
Binary file modified R/sysdata.rda
Binary file not shown.
3 changes: 3 additions & 0 deletions data-raw/X01-currencies.R
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,6 @@ currencies <-
file = "data-raw/x_currencies.csv",
col_types = "ccccc"
)

# Drop spec() attribute
currencies <- currencies[]
3 changes: 3 additions & 0 deletions data-raw/X02-currency_symbols.R
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,6 @@ currency_symbols <-
file = "data-raw/x_currency_symbols.csv",
col_types = "cc"
)

# Drop spec() attribute
currency_symbols <- currency_symbols[]
3 changes: 3 additions & 0 deletions data-raw/X07-fractions.R
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,6 @@ fractions <-
file = "data-raw/fractions.csv",
col_types = "ccccccccc"
)

# Drop spec() attribute
fractions <- fractions[]
3 changes: 3 additions & 0 deletions data-raw/X10-spelled_num.R
Original file line number Diff line number Diff line change
Expand Up @@ -87,3 +87,6 @@ spelled_num <-
zh = col_character()
)
)

# Drop spec() attribute
spelled_num <- spelled_num[]
3 changes: 3 additions & 0 deletions data-raw/X12-country_names.R
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,6 @@ country_names <-
col_types = cols(.default = col_character()),
na = ""
)

# Drop spec() attribute
country_names <- country_names[]
3 changes: 3 additions & 0 deletions data-raw/X13-country_names_additional.R
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,6 @@ country_names_additional <-
col_types = cols(.default = col_character()),
na = ""
)

# Drop spec() attribute
country_names_additional <- country_names_additional[]
3 changes: 3 additions & 0 deletions data-raw/X14-tf_words.R
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,6 @@ tf_words <-
file = "data-raw/tf_words.csv",
col_types = cols(.default = col_character())
)

# Drop spec() attribute
tf_words <- tf_words[]
15 changes: 15 additions & 0 deletions data-raw/X15-conversion_factors.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
library(tidyverse)

conversion_factors <-
readr::read_csv(
file = "data-raw/conversion_factors.csv",
col_types = cols(
type = col_character(),
from = col_character(),
to = col_character(),
conv_factor = col_double()
)
)

# Drop spec() attribute
conversion_factors <- conversion_factors[]
Loading
Loading