Skip to content

Commit

Permalink
alternative solution to r-quantities#89; r-quantities#91
Browse files Browse the repository at this point in the history
With this implementation, the symbolic units are preserved so they can be printed correctly, and assigning a unit like "mg/kg" no longer changes the numeric value of the target vector
  • Loading branch information
Tomasz Kalinowski committed Jan 23, 2018
1 parent 70a364a commit e7262af
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 8 deletions.
17 changes: 13 additions & 4 deletions R/make_units.R
Original file line number Diff line number Diff line change
Expand Up @@ -283,6 +283,15 @@ units_eval_env$ln <- function(x) base::log(x)
units_eval_env$lg <- function(x) base::log(x, base = 10)
units_eval_env$lb <- function(x) base::log(x, base = 2)

units_eval_env$`/` <- function(x, y) {
# don't cancel units, just combine them
units <- structure(list(
numerator = c(units(x)$numerator, units(y)$denominator),
denominator = c(units(y)$numerator, units(x)$denominator)),
class = "symbolic_units")
structure(1, units = units, class = "units")
}


#' @export
#' @rdname as_units
Expand Down Expand Up @@ -338,10 +347,10 @@ See ?as_units for usage examples.")
"Did you try to supply a value in a context where a bare expression was expected?"
), call. = FALSE ))

# if(as.numeric(unit) %not_in% c(1, 0)) # 0 if log() used.
# stop(call. = FALSE,
#"In ", sQuote(deparse(x)), " the numeric multiplier ", sQuote(as.numeric(unit)), " is invalid.
#Use `install_conversion_constant()` to define a new unit that is a multiple of another unit.")
if(as.numeric(unit) %not_in% c(1, 0)) # 0 if log() used.
stop(call. = FALSE,
"In ", sQuote(deparse(x)), " the numeric multiplier ", sQuote(as.numeric(unit)), " is invalid.
Use `install_conversion_constant()` to define a new unit that is a multiple of another unit.")

structure(as.numeric(unit), units = units(unit), class = "units")
}
Expand Down
16 changes: 12 additions & 4 deletions tests/testthat/test_conversion.R
Original file line number Diff line number Diff line change
Expand Up @@ -139,11 +139,19 @@ test_that("dim propagates", {
test_that("conversion to dimensionless with prefix works (g/kg)", {
a_orig <- a <- 1:10
units(a) = as_units("mg/kg")
expect_equal(as.numeric(a), a_orig/1e6)
# why should assigning units change the numeric value?
expect_equal(as.numeric(a), a_orig)

units(a) = as_units("kg/mg")
expect_equal(a, a_orig)
expect_equal(a, a_orig/1e12)

units(a) = as_units("g/g")
expect_equal(a, a_orig)
expect_equal(a, a_orig/1e6)

units(a) = as_units("kg/g")
expect_equal(a, a_orig * 1000)
expect_equal(a, a_orig / 1e9)

# back to original
units(a) <- as_units("mg/kg")
expect_equal(as.numeric(a), a_orig)
})

0 comments on commit e7262af

Please sign in to comment.