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

Cleanup and improvements in unit mapping #290

Merged
merged 4 commits into from
Nov 9, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
4 changes: 2 additions & 2 deletions DESCRIPTION
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
Package: units
Version: 0.7-3
Version: 0.8-0
Title: Measurement Units for R Vectors
Authors@R: c(person("Edzer", "Pebesma", role = c("aut", "cre"), email = "edzer.pebesma@uni-muenster.de", comment = c(ORCID = "0000-0001-8049-7069")),
person("Thomas", "Mailund", role = "aut", email = "mailund@birc.au.dk"),
Expand Down Expand Up @@ -41,7 +41,7 @@ SystemRequirements: udunits-2
License: GPL-2
URL: https://github.com/r-quantities/units/
BugReports: https://github.com/r-quantities/units/issues/
RoxygenNote: 7.1.1
RoxygenNote: 7.1.2
Roxygen: list(old_usage = TRUE)
Encoding: UTF-8
Config/testthat/edition: 3
4 changes: 0 additions & 4 deletions NAMESPACE
Original file line number Diff line number Diff line change
Expand Up @@ -71,16 +71,12 @@ export(as_difftime)
export(as_units)
export(deparse_unit)
export(drop_units)
export(install_conversion_constant)
export(install_conversion_offset)
export(install_symbolic_unit)
export(install_unit)
export(keep_units)
export(load_units_xml)
export(make_unit_label)
export(make_units)
export(mixed_units)
export(remove_symbolic_unit)
export(remove_unit)
export(set_units)
export(ud_are_convertible)
Expand Down
7 changes: 7 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
# version 0.8-0

* enhance unit mapping for newly installed units; #290

* remove deprecations: `install_symbolic_unit`, `remove_symbolic_unit`,
`install_conversion_constant`, `install_conversion_offset`; #290

# version 0.7-2

* enhance `pillar` integration; #273, #275, #280 @krlmlr
Expand Down
96 changes: 48 additions & 48 deletions R/RcppExports.R
Original file line number Diff line number Diff line change
@@ -1,99 +1,99 @@
# Generated by using Rcpp::compileAttributes() -> do not edit by hand
# Generator token: 10BE3573-1514-4C36-9D1C-5A225CD40393

udunits_exit <- function() {
invisible(.Call('_units_udunits_exit', PACKAGE = 'units'))
ud_exit <- function() {
invisible(.Call('_units_ud_exit', PACKAGE = 'units'))
}

udunits_init <- function(path) {
invisible(.Call('_units_udunits_init', PACKAGE = 'units', path))
ud_init <- function(path) {
invisible(.Call('_units_ud_init', PACKAGE = 'units', path))
}

R_ut_parse <- function(name) {
.Call('_units_R_ut_parse', PACKAGE = 'units', name)
ud_set_encoding <- function(enc_str) {
invisible(.Call('_units_ud_set_encoding', PACKAGE = 'units', enc_str))
}

R_ut_get_dimensionless_unit_one <- function() {
.Call('_units_R_ut_get_dimensionless_unit_one', PACKAGE = 'units')
ud_convert <- function(val, from, to) {
.Call('_units_ud_convert', PACKAGE = 'units', val, from, to)
}

R_ut_are_convertible <- function(a, b) {
.Call('_units_R_ut_are_convertible', PACKAGE = 'units', a, b)
ud_map_names <- function(names, inunit) {
invisible(.Call('_units_ud_map_names', PACKAGE = 'units', names, inunit))
}

R_convert_doubles <- function(from, to, val) {
.Call('_units_R_convert_doubles', PACKAGE = 'units', from, to, val)
ud_unmap_names <- function(names) {
invisible(.Call('_units_ud_unmap_names', PACKAGE = 'units', names))
}

R_ut_new_dimensionless_unit <- function() {
.Call('_units_R_ut_new_dimensionless_unit', PACKAGE = 'units')
ud_map_symbols <- function(symbols, inunit) {
invisible(.Call('_units_ud_map_symbols', PACKAGE = 'units', symbols, inunit))
}

R_ut_new_base_unit <- function() {
.Call('_units_R_ut_new_base_unit', PACKAGE = 'units')
ud_unmap_symbols <- function(symbols) {
invisible(.Call('_units_ud_unmap_symbols', PACKAGE = 'units', symbols))
}

R_ut_scale <- function(nw, old, d) {
invisible(.Call('_units_R_ut_scale', PACKAGE = 'units', nw, old, d))
R_ut_get_dimensionless_unit_one <- function() {
.Call('_units_R_ut_get_dimensionless_unit_one', PACKAGE = 'units')
}

R_ut_offset <- function(nw, old, d) {
invisible(.Call('_units_R_ut_offset', PACKAGE = 'units', nw, old, d))
R_ut_new_base_unit <- function() {
.Call('_units_R_ut_new_base_unit', PACKAGE = 'units')
}

R_ut_divide <- function(numer, denom) {
.Call('_units_R_ut_divide', PACKAGE = 'units', numer, denom)
R_ut_new_dimensionless_unit <- function() {
.Call('_units_R_ut_new_dimensionless_unit', PACKAGE = 'units')
}

R_ut_multiply <- function(a, b) {
.Call('_units_R_ut_multiply', PACKAGE = 'units', a, b)
R_ut_get_name <- function(unit) {
.Call('_units_R_ut_get_name', PACKAGE = 'units', unit)
}

R_ut_invert <- function(a) {
.Call('_units_R_ut_invert', PACKAGE = 'units', a)
R_ut_get_symbol <- function(unit) {
.Call('_units_R_ut_get_symbol', PACKAGE = 'units', unit)
}

R_ut_raise <- function(a, i) {
.Call('_units_R_ut_raise', PACKAGE = 'units', a, i)
R_ut_are_convertible <- function(a, b) {
.Call('_units_R_ut_are_convertible', PACKAGE = 'units', a, b)
}

R_ut_root <- function(a, i) {
.Call('_units_R_ut_root', PACKAGE = 'units', a, i)
R_ut_scale <- function(unit, factor) {
.Call('_units_R_ut_scale', PACKAGE = 'units', unit, factor)
}

R_ut_log <- function(a, base) {
.Call('_units_R_ut_log', PACKAGE = 'units', a, base)
R_ut_offset <- function(unit, origin) {
.Call('_units_R_ut_offset', PACKAGE = 'units', unit, origin)
}

R_ut_format <- function(p, names = FALSE, definition = FALSE, ascii = FALSE) {
.Call('_units_R_ut_format', PACKAGE = 'units', p, names, definition, ascii)
R_ut_multiply <- function(a, b) {
.Call('_units_R_ut_multiply', PACKAGE = 'units', a, b)
}

R_ut_set_encoding <- function(enc_str) {
invisible(.Call('_units_R_ut_set_encoding', PACKAGE = 'units', enc_str))
R_ut_invert <- function(a) {
.Call('_units_R_ut_invert', PACKAGE = 'units', a)
}

R_ut_get_symbol <- function(ustr) {
.Call('_units_R_ut_get_symbol', PACKAGE = 'units', ustr)
R_ut_divide <- function(numer, denom) {
.Call('_units_R_ut_divide', PACKAGE = 'units', numer, denom)
}

R_ut_get_name <- function(ustr) {
.Call('_units_R_ut_get_name', PACKAGE = 'units', ustr)
R_ut_raise <- function(a, i) {
.Call('_units_R_ut_raise', PACKAGE = 'units', a, i)
}

R_ut_map_name_to_unit <- function(name, inunit) {
invisible(.Call('_units_R_ut_map_name_to_unit', PACKAGE = 'units', name, inunit))
R_ut_root <- function(a, i) {
.Call('_units_R_ut_root', PACKAGE = 'units', a, i)
}

R_ut_unmap_name_to_unit <- function(name) {
invisible(.Call('_units_R_ut_unmap_name_to_unit', PACKAGE = 'units', name))
R_ut_log <- function(a, base) {
.Call('_units_R_ut_log', PACKAGE = 'units', a, base)
}

R_ut_map_symbol_to_unit <- function(name, inunit) {
invisible(.Call('_units_R_ut_map_symbol_to_unit', PACKAGE = 'units', name, inunit))
R_ut_parse <- function(name) {
.Call('_units_R_ut_parse', PACKAGE = 'units', name)
}

R_ut_unmap_symbol_to_unit <- function(name) {
invisible(.Call('_units_R_ut_unmap_symbol_to_unit', PACKAGE = 'units', name))
R_ut_format <- function(p, names = FALSE, definition = FALSE, ascii = FALSE) {
.Call('_units_R_ut_format', PACKAGE = 'units', p, names, definition, ascii)
}

2 changes: 1 addition & 1 deletion R/database.R
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ default_units_xml <- function(warn = FALSE) {
#'
#' @export
load_units_xml <- function(path = default_units_xml()) {
udunits_init(path)
ud_init(path)
}

.read_ud_db <- function(path = default_units_xml(), type) {
Expand Down
18 changes: 18 additions & 0 deletions R/defunct.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
#' Defunct functions in \pkg{units}
#'
#' These functions are no longer available.
#'
#' \itemize{
#' \item \code{ud_units}: Use \code{\link{as_units}} instead.
#' \item \code{as.units}: Use \code{\link{as_units}} instead.
#' \item \code{make_unit}: Use \code{\link{as_units}} instead.
#' \item \code{parse_unit}: Use \code{\link{as_units}} instead.
#' \item \code{as_cf}: Use \code{\link{deparse_unit}} instead.
#' \item \code{install_symbolic_unit}: Use \code{\link{install_unit}} instead.
#' \item \code{remove_symbolic_unit}: Use \code{\link{remove_unit}} instead.
#' \item \code{install_conversion_constant}: Use \code{\link{install_unit}} instead.
#' \item \code{install_conversion_offset}: Use \code{\link{install_unit}} instead.
#' }
#'
#' @name units-defunct
NULL
4 changes: 2 additions & 2 deletions R/init.R
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,9 @@ NULL
}

.onAttach <- function(libname, pkgname) {
packageStartupMessage(.startup_msg(TRUE))
packageStartupMessage(.startup_msg(TRUE))
}

.onUnload = function(libname, pkgname) {
udunits_exit()
ud_exit()
}
4 changes: 0 additions & 4 deletions R/make_units.R
Original file line number Diff line number Diff line change
Expand Up @@ -66,10 +66,6 @@
#' make_units(degree_C)
#' make_units(kilogram)
#' make_units(ohm)
#' # Note, if the printing of non-ascii characters is garbled, then you may
#' # need to specify the encoding on your system manually like this:
#' # ud_set_encoding("latin1")
#' # not all unit names get converted to symbols under different encodings
#'
#' ## Arithmetic operations and units
#' # conversion between unit objects that were defined as symbols and names will
Expand Down
9 changes: 1 addition & 8 deletions R/udunits.R
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ ud_are_convertible = function(x, y) {
}

ud_get_symbol = function(u) {
u <- R_ut_parse(u)
sym = R_ut_get_symbol(u)
if (!length(sym))
sym = R_ut_get_name(u)
Expand All @@ -34,11 +35,3 @@ ud_is_parseable = function(u) {
res <- try(R_ut_parse(u), silent = TRUE)
! inherits(res, "try-error")
}

ud_convert = function(value, from, to) {
R_convert_doubles(R_ut_parse(from), R_ut_parse(to), value)
}

ud_set_encoding = function(enc) {
R_ut_set_encoding(as.character(enc))
}
111 changes: 4 additions & 107 deletions R/user_conversion.R
Original file line number Diff line number Diff line change
Expand Up @@ -82,8 +82,8 @@ install_unit <- function(symbol=character(0), def=character(0), name=character(0
ut_unit <- R_ut_parse(def)
}

R_ut_map_symbol_to_unit(symbol, ut_unit)
R_ut_map_name_to_unit(name, ut_unit)
ud_map_symbols(symbol, ut_unit)
ud_map_names(name, ut_unit)
}

#' @rdname install_unit
Expand All @@ -93,109 +93,6 @@ remove_unit <- function(symbol=character(0), name=character(0)) {
if (!length(symbol) && !length(name))
stop("at least one symbol or name must be specified")

R_ut_unmap_symbol_to_unit(symbol)
R_ut_unmap_name_to_unit(name)
ud_unmap_symbols(symbol)
ud_unmap_names(name)
}

#' Define new symbolic units
#'
#' Adding a symbolic unit allows it to be used in \code{as_units},
#' \code{make_units} and \code{set_units}. No installation is performed if the
#' unit is already known by udunits.
#'
#' @param name a length 1 character vector that is the unit name or symbol.
#' @param warn warns if the supplied unit symbol is already a valid unit symbol
#' recognized by udunits.
#' @param dimensionless logical; if \code{TRUE}, a new dimensionless unit is
#' created, if \code{FALSE} a new base unit is created. Dimensionless units are
#' convertible to other dimensionless units (such as \code{rad}), new base units
#' are not convertible to other existing units.
#'
#' @details \code{install_symbolic_unit} installs a new dimensionless unit;
#' these are directly compatible to any other dimensionless unit. To install a
#' new unit that is a scaled or shifted version of an existing unit, use
#' \code{install_conversion_constant} or \code{install_conversion_offset} directly.ç
#'
#' @export
install_symbolic_unit <- function(name, warn = TRUE, dimensionless = TRUE) {# nocov start
.Deprecated("install_unit")
check_unit_format(name)

if(ud_is_parseable(name)) {
if (warn) warning(
sQuote(name), " is already a valid unit recognized by udunits; removing and reinstalling.")
remove_symbolic_unit(name)
}

ut_unit <- if (dimensionless)
R_ut_new_dimensionless_unit() else R_ut_new_base_unit()
R_ut_map_name_to_unit(name, ut_unit)

invisible(NULL)
}# nocov end

#' @export
#' @rdname install_symbolic_unit
remove_symbolic_unit <- function(name) {# nocov start
.Deprecated("remove_unit")
remove_unit(name=name)
}# nocov end

#' Install a conversion constant or offset between user-defined units.
#'
#' Tells the \code{units} package how to convert between units that
#' have a linear relationship, i.e. can be related on the form \eqn{y = \alpha
#' x} (constant) or \eqn{y = \alpha + x} (offset).
#'
#' @param from String for the symbol of the unit being converted from.
#' @param to String for the symbol of the unit being converted to. One of
#' \code{from} and \code{to} must be an existing unit name.
#' @param const The constant \eqn{\alpha} in the conversion.
#'
#' @details This function handles the very common case where units are related
#' through a linear function, that is, you can convert from one to the other
#' as \eqn{y = \alpha x}. Using this function, you specify that you
#' can go from values of type \code{from} to values of type \code{to} by
#' multiplying by a constant, or adding a constant.
#'
#' @export
install_conversion_constant <- function(from, to, const) {# nocov start
.Deprecated("install_unit")
stopifnot(is.finite(const), const != 0.0)
if (! xor(ud_is_parseable(from), ud_is_parseable(to)))
stop("exactly one of (from, to) must be a known unit")
if (ud_is_parseable(to))
R_ut_scale(check_unit_format(from), to, as.double(const))
else
R_ut_scale(check_unit_format(to), from, 1.0 / as.double(const))
}# nocov end

#' @export
#' @name install_conversion_constant
install_conversion_offset <- function(from, to, const) {# nocov start
.Deprecated("install_unit")
stopifnot(is.finite(const))
if (! xor(ud_is_parseable(from), ud_is_parseable(to)))
stop("exactly one of (from, to) must be a known unit")
if (ud_is_parseable(to))
R_ut_offset(check_unit_format(from), to, -as.double(const))
else
R_ut_offset(check_unit_format(to), from, as.double(const))
}# nocov end

check_unit_format <- function(x) {# nocov start
cond <- c(
# leading and trailing numbers
grepl("^[[:space:]]*[0-9]+", x), grepl("[0-9]+[[:space:]]*$", x),
# arithmetic operators
grepl("\\+|\\-|\\*|\\/|\\^", x),
# intermediate spaces
grepl("[[:alnum:][:punct:]]+[[:space:]]+[[:alnum:][:punct:]]+", x)
)
if (any(cond))
stop("the following elements are not allowed in new unit names/symbols:\n",
" - leading or trailing numbers\n",
" - arithmetic operators\n",
" - intermediate white spaces")
x
}# nocov end
Loading