From 1ed7b9ae09a4fc25cf18c8cdf14009895867cc50 Mon Sep 17 00:00:00 2001 From: Teun van den Brand <49372158+teunbrand@users.noreply.github.com> Date: Tue, 7 Nov 2023 12:38:36 +0100 Subject: [PATCH] Transformation suffixes to prefixes (attempt 2) (#410) --- NAMESPACE | 34 ++- NEWS.md | 23 +- R/documentation.R | 2 +- R/scale-continuous.R | 6 +- R/{trans-compose.R => transform-compose.R} | 12 +- R/{trans-date.R => transform-date.R} | 62 +++-- R/{trans-numeric.R => transform-numeric.R} | 249 ++++++++++++------ R/{trans.R => transform.R} | 67 +++-- README.Rmd | 6 +- README.md | 6 +- man/cscale.Rd | 6 +- man/log_trans.Rd | 48 ---- man/{trans_new.Rd => new_transform.Rd} | 27 +- man/pal_shape.Rd | 2 +- man/trans_range.Rd | 18 -- man/{asinh_trans.Rd => transform_asinh.Rd} | 9 +- man/{asn_trans.Rd => transform_asn.Rd} | 9 +- man/{atanh_trans.Rd => transform_atanh.Rd} | 9 +- man/{boxcox_trans.Rd => transform_boxcox.Rd} | 30 ++- ...{compose_trans.Rd => transform_compose.Rd} | 7 +- man/{date_trans.Rd => transform_date.Rd} | 9 +- man/{exp_trans.Rd => transform_exp.Rd} | 15 +- ...dentity_trans.Rd => transform_identity.Rd} | 9 +- man/transform_log.Rd | 63 +++++ ...lity_trans.Rd => transform_probability.Rd} | 17 +- ...rocal_trans.Rd => transform_reciprocal.Rd} | 9 +- ...{reverse_trans.Rd => transform_reverse.Rd} | 9 +- man/{sqrt_trans.Rd => transform_sqrt.Rd} | 9 +- man/{time_trans.Rd => transform_time.Rd} | 9 +- ...imespan_trans.Rd => transform_timespan.Rd} | 28 +- man/{yj_trans.Rd => transform_yj.Rd} | 21 +- man/trim_to_domain.Rd | 21 ++ tests/testthat/_snaps/trans-compose.md | 10 +- tests/testthat/_snaps/trans-date.md | 4 +- tests/testthat/_snaps/trans.md | 12 +- tests/testthat/test-trans-compose.R | 24 +- tests/testthat/test-trans-date.R | 14 +- tests/testthat/test-trans-numeric.R | 110 ++++---- tests/testthat/test-trans.R | 22 +- 39 files changed, 647 insertions(+), 400 deletions(-) rename R/{trans-compose.R => transform-compose.R} (90%) rename R/{trans-date.R => transform-date.R} (66%) rename R/{trans-numeric.R => transform-numeric.R} (66%) rename R/{trans.R => transform.R} (68%) delete mode 100644 man/log_trans.Rd rename man/{trans_new.Rd => new_transform.Rd} (80%) delete mode 100644 man/trans_range.Rd rename man/{asinh_trans.Rd => transform_asinh.Rd} (55%) rename man/{asn_trans.Rd => transform_asn.Rd} (60%) rename man/{atanh_trans.Rd => transform_atanh.Rd} (52%) rename man/{boxcox_trans.Rd => transform_boxcox.Rd} (70%) rename man/{compose_trans.Rd => transform_compose.Rd} (82%) rename man/{date_trans.Rd => transform_date.Rd} (71%) rename man/{exp_trans.Rd => transform_exp.Rd} (50%) rename man/{identity_trans.Rd => transform_identity.Rd} (54%) create mode 100644 man/transform_log.Rd rename man/{probability_trans.Rd => transform_probability.Rd} (66%) rename man/{reciprocal_trans.Rd => transform_reciprocal.Rd} (51%) rename man/{reverse_trans.Rd => transform_reverse.Rd} (69%) rename man/{sqrt_trans.Rd => transform_sqrt.Rd} (59%) rename man/{time_trans.Rd => transform_time.Rd} (78%) rename man/{timespan_trans.Rd => transform_timespan.Rd} (53%) rename man/{yj_trans.Rd => transform_yj.Rd} (73%) create mode 100644 man/trim_to_domain.Rd diff --git a/NAMESPACE b/NAMESPACE index ca790b6c..71ad1aa8 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -4,13 +4,13 @@ S3method(fullseq,Date) S3method(fullseq,POSIXt) S3method(fullseq,difftime) S3method(fullseq,numeric) -S3method(lines,trans) +S3method(lines,transform) S3method(offset_by,Date) S3method(offset_by,POSIXt) S3method(offset_by,difftime) S3method(offset_by,numeric) -S3method(plot,trans) -S3method(print,trans) +S3method(plot,transform) +S3method(print,transform) S3method(rescale,"NULL") S3method(rescale,AsIs) S3method(rescale,Date) @@ -37,6 +37,7 @@ export(abs_area) export(alpha) export(area_pal) export(as.trans) +export(as.transform) export(asinh_trans) export(asn_trans) export(atanh_trans) @@ -89,6 +90,7 @@ export(hue_pal) export(identity_pal) export(identity_trans) export(is.trans) +export(is.transform) export(label_bytes) export(label_comma) export(label_currency) @@ -121,6 +123,7 @@ export(minor_breaks_n) export(minor_breaks_width) export(modulus_trans) export(muted) +export(new_transform) export(number) export(number_bytes) export(number_bytes_format) @@ -185,6 +188,31 @@ export(trans_breaks) export(trans_format) export(trans_new) export(trans_range) +export(transform_asinh) +export(transform_asn) +export(transform_atanh) +export(transform_boxcox) +export(transform_compose) +export(transform_date) +export(transform_exp) +export(transform_hms) +export(transform_identity) +export(transform_log) +export(transform_log10) +export(transform_log1p) +export(transform_log2) +export(transform_logit) +export(transform_modulus) +export(transform_probability) +export(transform_probit) +export(transform_pseudo_log) +export(transform_reciprocal) +export(transform_reverse) +export(transform_sqrt) +export(transform_time) +export(transform_timespan) +export(transform_yj) +export(trim_to_domain) export(unit_format) export(viridis_pal) export(wrap_format) diff --git a/NEWS.md b/NEWS.md index e4203437..5e2ff322 100644 --- a/NEWS.md +++ b/NEWS.md @@ -17,22 +17,27 @@ make it easier to align positive and negative values as figure space takes up the same amount of space as `-` (#366) * `label_dollar()` has been superseeded by `label_currency()` for clarity (#344) -* `sqrt_trans()` no longer returns an inverse for values outside of its domain - (#214) +* `transform_sqrt()` no longer returns an inverse for values outside of its + domain (#214) * Add better support for `difftime` objects. `label_timespan()` adds functionality for adding correct unit suffix to timespan data, `breaks_timespan()` adds functionality for finding pleasant breakpoints across - the various bases in time units, while `timespan_trans()` wraps it all - together and provides an alternative to `hms_trans()` (#212) -* Add an inverse (area) hyperbolic sine transformation `asinh_trans()`, which - provides a logarithm-like transformation of a space, but which accommodates - negative values (#297) -* Correct the domain calculation for `compose_trans()` (@mjskay, #408). + the various bases in time units, while `transform_timespan()` wraps it all + together and provides an alternative to `transform_hms()` (#212) +* Add an inverse (area) hyperbolic sine transformation `transform_asinh()`, + which provides a logarithm-like transformation of a space, but which + accommodates negative values (#297) +* Correct the domain calculation for `transform_compose()` (@mjskay, #408). * Transformation objects can optionally include the derivatives of the transform and the inverse transform (@mjskay, #322). +* Transformation function have been renamed to `transform_*`-prefixed names + instead of `*_trans`-suffixed names. This allows for a better tab-completion + search of transformations. The S3 class of transformations has been + renamed from `"trans"` to `"transform"`. `new_transform()` replaces + `trans_new()` and `trim_to_domain()` replaces `trans_range()`. * Palette functions now have the `pal_`-prefix. The old `_pal`-suffixed versions are kept for backward compatibility. - + # scales 1.2.1 * Re-document to fix HTML issues in `.Rd`. diff --git a/R/documentation.R b/R/documentation.R index 594c942f..0442f01b 100644 --- a/R/documentation.R +++ b/R/documentation.R @@ -7,6 +7,6 @@ seealso <- function(pattern) { paste0("\\code{\\link{", names, "}}", collapse = ", ") } -seealso_trans <- function() seealso("_trans$") +seealso_transform <- function() seealso("^transform_") seealso_pal <- function() seealso("^pal_") diff --git a/R/scale-continuous.R b/R/scale-continuous.R index f49c3f68..102b325f 100644 --- a/R/scale-continuous.R +++ b/R/scale-continuous.R @@ -11,19 +11,19 @@ #' leaves the data unchanged. #' #' Built in transformations: -#' \Sexpr[results=rd,stage=build]{scales:::seealso_trans()}. +#' \Sexpr[results=rd,stage=build]{scales:::seealso_transform()}. #' @export #' @examples #' with(mtcars, plot(disp, mpg, cex = cscale(hp, pal_rescale()))) #' with(mtcars, plot(disp, mpg, cex = cscale(hp, pal_rescale(), -#' trans = sqrt_trans() +#' trans = transform_sqrt() #' ))) #' with(mtcars, plot(disp, mpg, cex = cscale(hp, pal_area()))) #' with(mtcars, plot(disp, mpg, #' pch = 20, cex = 5, #' col = cscale(hp, pal_seq_gradient("grey80", "black")) #' )) -cscale <- function(x, palette, na.value = NA_real_, trans = identity_trans()) { +cscale <- function(x, palette, na.value = NA_real_, trans = transform_identity()) { if (!is.trans(trans)) cli::cli_abort("{.arg trans} must be a {.cls trans} object") x <- trans$transform(x) diff --git a/R/trans-compose.R b/R/transform-compose.R similarity index 90% rename from R/trans-compose.R rename to R/transform-compose.R index 4cd1330a..4af412f4 100644 --- a/R/trans-compose.R +++ b/R/transform-compose.R @@ -10,10 +10,10 @@ #' @examples #' demo_continuous(10^c(-2:4), trans = "log10", labels = label_log()) #' demo_continuous(10^c(-2:4), trans = c("log10", "reverse"), labels = label_log()) -compose_trans <- function(...) { - trans_list <- lapply(list2(...), as.trans) +transform_compose <- function(...) { + trans_list <- lapply(list2(...), as.transform) if (length(trans_list) == 0) { - cli::cli_abort("{.fun compose_trans} must include at least 1 transformer to compose") + cli::cli_abort("{.fun transform_compose} must include at least 1 transformer to compose") } # Resolve domains. First push the domain of the first transformation all the @@ -42,7 +42,7 @@ compose_trans <- function(...) { has_d_transform <- all(lengths(lapply(trans_list, "[[", "d_transform")) > 0) has_d_inverse <- all(lengths(lapply(trans_list, "[[", "d_inverse")) > 0) - trans_new( + new_transform( paste0("composition(", paste0(names, collapse = ","), ")"), transform = function(x) compose_fwd(x, trans_list), inverse = function(x) compose_rev(x, trans_list), @@ -53,6 +53,10 @@ compose_trans <- function(...) { ) } +#' @export +#' @rdname transform_compose +compose_trans <- transform_compose + compose_fwd <- function(x, trans_list) { for (trans in trans_list) { x <- trans$transform(x) diff --git a/R/trans-date.R b/R/transform-date.R similarity index 66% rename from R/trans-date.R rename to R/transform-date.R index 9a17ce0c..f17e7a52 100644 --- a/R/trans-date.R +++ b/R/transform-date.R @@ -3,12 +3,13 @@ #' @export #' @examples #' years <- seq(as.Date("1910/1/1"), as.Date("1999/1/1"), "years") -#' t <- date_trans() +#' t <- transform_date() #' t$transform(years) #' t$inverse(t$transform(years)) #' t$format(t$breaks(range(years))) -date_trans <- function() { - trans_new("date", +transform_date <- function() { + new_transform( + "date", transform = "from_date", inverse = "to_date", breaks = breaks_pretty(), @@ -16,10 +17,14 @@ date_trans <- function() { ) } +#' @export +#' @rdname transform_date +date_trans <- transform_date + to_date <- function(x) structure(x, class = "Date") from_date <- function(x) { if (!inherits(x, "Date")) { - cli::cli_abort("{.fun date_trans} works with objects of class {.cls Date} only") + cli::cli_abort("{.fun transform_date} works with objects of class {.cls Date} only") } structure(as.numeric(x), names = names(x)) } @@ -31,11 +36,11 @@ from_date <- function(x) { #' @export #' @examples #' hours <- seq(ISOdate(2000, 3, 20, tz = ""), by = "hour", length.out = 10) -#' t <- time_trans() +#' t <- transform_time() #' t$transform(hours) #' t$inverse(t$transform(hours)) #' t$format(t$breaks(range(hours))) -time_trans <- function(tz = NULL) { +transform_time <- function(tz = NULL) { force(tz) to_time <- function(x) { structure(x, class = c("POSIXt", "POSIXct"), tzone = tz) @@ -43,7 +48,7 @@ time_trans <- function(tz = NULL) { from_time <- function(x) { if (!inherits(x, "POSIXct")) { - cli::cli_abort("{.fun time_trans} works with objects of class {.cls POSIXct} only") + cli::cli_abort("{.fun transform_time} works with objects of class {.cls POSIXct} only") } if (is.null(tz)) { tz <<- attr(as.POSIXlt(x), "tzone")[[1]] @@ -51,7 +56,7 @@ time_trans <- function(tz = NULL) { structure(as.numeric(x), names = names(x)) } - trans_new("time", + new_transform("time", transform = "from_time", inverse = "to_time", breaks = breaks_pretty(), @@ -59,27 +64,31 @@ time_trans <- function(tz = NULL) { ) } +#' @export +#' @rdname transform_time +time_trans <- transform_time + #' Transformation for times (class hms) #' -#' `timespan_trans()` provides transformations for data encoding time passed +#' `transform_timespan()` provides transformations for data encoding time passed #' along with breaks and label formatting showing standard unit of time fitting -#' the range of the data. `hms_trans()` provides the same but using standard hms -#' idioms and formatting. +#' the range of the data. `transform_hms()` provides the same but using standard +#' hms idioms and formatting. #' #' @inheritParams label_timespan #' @export #' @examples -#' # timespan_trans allows you to specify the time unit numeric data is +#' # transform_timespan allows you to specify the time unit numeric data is #' # interpreted in -#' min_trans <- timespan_trans("mins") -#' demo_timespan(seq(0, 100), trans = min_trans) +#' trans_min <- transform_timespan("mins") +#' demo_timespan(seq(0, 100), trans = trans_min) #' # Input already in difftime format is interpreted correctly -#' demo_timespan(as.difftime(seq(0, 100), units = "secs"), trans = min_trans) +#' demo_timespan(as.difftime(seq(0, 100), units = "secs"), trans = trans_min) #' #' if (require("hms")) { -#' # hms_trans always assumes seconds +#' # transform_hms always assumes seconds #' hms <- round(runif(10) * 86400) -#' t <- hms_trans() +#' t <- transform_hms() #' t$transform(hms) #' t$inverse(t$transform(hms)) #' t$breaks(hms) @@ -87,9 +96,9 @@ time_trans <- function(tz = NULL) { #' demo_timespan(hms, trans = t) #' } #' -timespan_trans <- function(unit = c("secs", "mins", "hours", "days", "weeks")) { +transform_timespan <- function(unit = c("secs", "mins", "hours", "days", "weeks")) { unit <- arg_match(unit) - trans_new( + new_transform( "timespan", transform = function(x) { structure(as.numeric(as.difftime(x, units = unit), units = "secs"), names = names(x)) @@ -103,10 +112,15 @@ timespan_trans <- function(unit = c("secs", "mins", "hours", "days", "weeks")) { format = label_timespan(unit) ) } -#' @rdname timespan_trans + #' @export -hms_trans <- function() { - trans_new( +#' @rdname transform_timespan +timespan_trans <- transform_timespan + +#' @rdname transform_timespan +#' @export +transform_hms <- function() { + new_transform( "hms", transform = function(x) { structure(as.numeric(x), names = names(x)) @@ -116,6 +130,10 @@ hms_trans <- function() { ) } +#' @rdname transform_timespan +#' @export +hms_trans <- transform_hms + breaks_hms <- function(n = 5) { base_breaks <- breaks_timespan("secs", n) function(x) { diff --git a/R/trans-numeric.R b/R/transform-numeric.R similarity index 66% rename from R/trans-numeric.R rename to R/transform-numeric.R index 301e15b0..641b7f53 100644 --- a/R/trans-numeric.R +++ b/R/transform-numeric.R @@ -5,9 +5,9 @@ #' #' @export #' @examples -#' plot(asn_trans(), xlim = c(0, 1)) -asn_trans <- function() { - trans_new( +#' plot(transform_asn(), xlim = c(0, 1)) +transform_asn <- function() { + new_transform( "asn", function(x) 2 * asin(sqrt(x)), function(x) sin(x / 2)^2, @@ -17,13 +17,17 @@ asn_trans <- function() { ) } +#' @rdname transform_asn +#' @export +asn_trans <- transform_asn + #' Arc-tangent transformation #' #' @export #' @examples -#' plot(atanh_trans(), xlim = c(-1, 1)) -atanh_trans <- function() { - trans_new( +#' plot(transform_atanh(), xlim = c(-1, 1)) +transform_atanh <- function() { + new_transform( "atanh", "atanh", "tanh", @@ -33,13 +37,17 @@ atanh_trans <- function() { ) } +#' @export +#' @rdname transform_atanh +atanh_trans <- transform_atanh + #' Inverse Hyperbolic Sine transformation #' #' @export #' @examples -#' plot(asinh_trans(), xlim = c(-1e2, 1e2)) -asinh_trans <- function() { - trans_new( +#' plot(transform_asinh(), xlim = c(-1e2, 1e2)) +transform_asinh <- function() { + new_transform( "asinh", transform = asinh, inverse = sinh, @@ -48,6 +56,10 @@ asinh_trans <- function() { ) } +#' @export +#' @rdname transform_asinh +asinh_trans <- transform_asinh + #' Box-Cox & modulus transformations #' #' The Box-Cox transformation is a flexible transformation, often used to @@ -69,9 +81,9 @@ asinh_trans <- function() { #' #' @param p Transformation exponent, \eqn{\lambda}. #' @param offset Constant offset. 0 for Box-Cox type 1, -#' otherwise any non-negative constant (Box-Cox type 2). `modulus_trans()` +#' otherwise any non-negative constant (Box-Cox type 2). `transform_modulus()` #' sets the default to 1. -#' @seealso [yj_trans()] +#' @seealso [transform_yj()] #' @references Box, G. E., & Cox, D. R. (1964). An analysis of transformations. #' Journal of the Royal Statistical Society. Series B (Methodological), 211-252. #' \url{https://www.jstor.org/stable/2984418} @@ -81,16 +93,16 @@ asinh_trans <- function() { #' \url{https://www.jstor.org/stable/2986305} #' @export #' @examples -#' plot(boxcox_trans(-1), xlim = c(0, 10)) -#' plot(boxcox_trans(0), xlim = c(0, 10)) -#' plot(boxcox_trans(1), xlim = c(0, 10)) -#' plot(boxcox_trans(2), xlim = c(0, 10)) +#' plot(transform_boxcox(-1), xlim = c(0, 10)) +#' plot(transform_boxcox(0), xlim = c(0, 10)) +#' plot(transform_boxcox(1), xlim = c(0, 10)) +#' plot(transform_boxcox(2), xlim = c(0, 10)) #' -#' plot(modulus_trans(-1), xlim = c(-10, 10)) -#' plot(modulus_trans(0), xlim = c(-10, 10)) -#' plot(modulus_trans(1), xlim = c(-10, 10)) -#' plot(modulus_trans(2), xlim = c(-10, 10)) -boxcox_trans <- function(p, offset = 0) { +#' plot(transform_modulus(-1), xlim = c(-10, 10)) +#' plot(transform_modulus(0), xlim = c(-10, 10)) +#' plot(transform_modulus(1), xlim = c(-10, 10)) +#' plot(transform_modulus(2), xlim = c(-10, 10)) +transform_boxcox <- function(p, offset = 0) { if (abs(p) < 1e-07) { trans <- function(x) log(x + offset) inv <- function(x) exp(x) - offset @@ -106,14 +118,14 @@ boxcox_trans <- function(p, offset = 0) { trans_with_check <- function(x) { if (any((x + offset) < 0, na.rm = TRUE)) { cli::cli_abort(c( - "{.fun boxcox_trans} must be given only positive values", - i = "Consider using {.fun modulus_trans} instead?" + "{.fun transform_boxcox} must be given only positive values", + i = "Consider using {.fun transform_modulus} instead?" )) } trans(x) } - trans_new( + new_transform( paste0("pow-", format(p)), trans_with_check, inv, @@ -123,9 +135,13 @@ boxcox_trans <- function(p, offset = 0) { ) } -#' @rdname boxcox_trans #' @export -modulus_trans <- function(p, offset = 1) { +#' @rdname transform_boxcox +boxcox_trans <- transform_boxcox + +#' @rdname transform_boxcox +#' @export +transform_modulus <- function(p, offset = 1) { if (abs(p) < 1e-07) { trans <- function(x) sign(x) * log(abs(x) + offset) inv <- function(x) sign(x) * (exp(abs(x)) - offset) @@ -137,17 +153,21 @@ modulus_trans <- function(p, offset = 1) { d_trans <- function(x) (abs(x) + offset)^(p - 1) d_inv <- function(x) (abs(x) * p + 1)^(1 / p - 1) } - trans_new( + new_transform( paste0("mt-pow-", format(p)), trans, inv, d_transform = d_trans, d_inverse = d_inv ) } +#' @rdname transform_boxcox +#' @export +modulus_trans <- transform_modulus + #' Yeo-Johnson transformation #' -#' The Yeo-Johnson transformation is a flexible transformation that is similiar -#' to Box-Cox, [boxcox_trans()], but does not require input values to be greater -#' than zero. +#' The Yeo-Johnson transformation is a flexible transformation that is similar +#' to Box-Cox, [transform_boxcox()], but does not require input values to be +#' greater than zero. #' #' The transformation takes one of four forms depending on the values of `y` and \eqn{\lambda}. #' @@ -166,11 +186,11 @@ modulus_trans <- function(p, offset = 1) { #' \url{https://www.jstor.org/stable/2673623} #' @export #' @examples -#' plot(yj_trans(-1), xlim = c(-10, 10)) -#' plot(yj_trans(0), xlim = c(-10, 10)) -#' plot(yj_trans(1), xlim = c(-10, 10)) -#' plot(yj_trans(2), xlim = c(-10, 10)) -yj_trans <- function(p) { +#' plot(transform_yj(-1), xlim = c(-10, 10)) +#' plot(transform_yj(0), xlim = c(-10, 10)) +#' plot(transform_yj(1), xlim = c(-10, 10)) +#' plot(transform_yj(2), xlim = c(-10, 10)) +transform_yj <- function(p) { eps <- 1e-7 if (abs(p) < eps) { @@ -197,7 +217,7 @@ yj_trans <- function(p) { d_inv_neg <- function(x) (-(2 - p) * x + 1)^(1 / (2 - p) - 1) } - trans_new( + new_transform( paste0("yeo-johnson-", format(p)), function(x) trans_two_sided(x, trans_pos, trans_neg), function(x) trans_two_sided(x, inv_pos, inv_neg), @@ -206,6 +226,10 @@ yj_trans <- function(p) { ) } +#' @export +#' @rdname transform_yj +yj_trans <- transform_yj + trans_two_sided <- function(x, pos, neg, f_at_0 = 0) { out <- rep(NA_real_, length(x)) present <- !is.na(x) @@ -220,13 +244,13 @@ trans_two_sided <- function(x, pos, neg, f_at_0 = 0) { #' @param base Base of logarithm #' @export #' @examples -#' plot(exp_trans(0.5), xlim = c(-2, 2)) -#' plot(exp_trans(1), xlim = c(-2, 2)) -#' plot(exp_trans(2), xlim = c(-2, 2)) -#' plot(exp_trans(), xlim = c(-2, 2)) -exp_trans <- function(base = exp(1)) { +#' plot(transform_exp(0.5), xlim = c(-2, 2)) +#' plot(transform_exp(1), xlim = c(-2, 2)) +#' plot(transform_exp(2), xlim = c(-2, 2)) +#' plot(transform_exp(), xlim = c(-2, 2)) +transform_exp <- function(base = exp(1)) { force(base) - trans_new( + new_transform( paste0("power-", format(base)), function(x) base^x, function(x) log(x, base = base), @@ -235,13 +259,17 @@ exp_trans <- function(base = exp(1)) { ) } +#' @export +#' @rdname transform_exp +exp_trans <- transform_exp + #' Identity transformation (do nothing) #' #' @export #' @examples -#' plot(identity_trans(), xlim = c(-1, 1)) -identity_trans <- function() { - trans_new( +#' plot(transform_identity(), xlim = c(-1, 1)) +transform_identity <- function() { + new_transform( "identity", "force", "force", @@ -250,33 +278,37 @@ identity_trans <- function() { ) } +#' @export +#' @rdname transform_identity +identity_trans <- transform_identity + #' Log transformations #' -#' * `log_trans()`: `log(x)` +#' * `transform_log()`: `log(x)` #' * `log1p()`: `log(x + 1)` -#' * `pseudo_log_trans()`: smoothly transition to linear scale around 0. +#' * `transform_pseudo_log()`: smoothly transition to linear scale around 0. #' #' @param base base of logarithm #' @export #' @examples -#' plot(log2_trans(), xlim = c(0, 5)) -#' plot(log_trans(), xlim = c(0, 5)) -#' plot(log10_trans(), xlim = c(0, 5)) +#' plot(transform_log2(), xlim = c(0, 5)) +#' plot(transform_log(), xlim = c(0, 5)) +#' plot(transform_log10(), xlim = c(0, 5)) #' -#' plot(log_trans(), xlim = c(0, 2)) -#' plot(log1p_trans(), xlim = c(-1, 1)) +#' plot(transform_log(), xlim = c(0, 2)) +#' plot(transform_log1p(), xlim = c(-1, 1)) #' #' # The pseudo-log is defined for all real numbers -#' plot(pseudo_log_trans(), xlim = c(-5, 5)) -#' lines(log_trans(), xlim = c(0, 5), col = "red") +#' plot(transform_pseudo_log(), xlim = c(-5, 5)) +#' lines(transform_log(), xlim = c(0, 5), col = "red") #' -#' # For large positives nubmers it's very close to log -#' plot(pseudo_log_trans(), xlim = c(1, 20)) -#' lines(log_trans(), xlim = c(1, 20), col = "red") -log_trans <- function(base = exp(1)) { +#' # For large positives numbers it's very close to log +#' plot(transform_pseudo_log(), xlim = c(1, 20)) +#' lines(transform_log(), xlim = c(1, 20), col = "red") +transform_log <- function(base = exp(1)) { force(base) - trans_new( + new_transform( paste0("log-", format(base)), function(x) log(x, base), function(x) base^x, @@ -287,21 +319,21 @@ log_trans <- function(base = exp(1)) { ) } #' @export -#' @rdname log_trans -log10_trans <- function() { - log_trans(10) +#' @rdname transform_log +transform_log10 <- function() { + transform_log(10) } #' @export -#' @rdname log_trans -log2_trans <- function() { - log_trans(2) +#' @rdname transform_log +transform_log2 <- function() { + transform_log(2) } -#' @rdname log_trans +#' @rdname transform_log #' @export -log1p_trans <- function() { - trans_new( +transform_log1p <- function() { + new_transform( "log1p", "log1p", "expm1", @@ -311,11 +343,25 @@ log1p_trans <- function() { ) } -#' @rdname log_trans +#' @export +#' @rdname transform_log +log_trans <- transform_log +#' @export +#' @rdname transform_log +log10_trans <- transform_log10 +#' @export +#' @rdname transform_log +log2_trans <- transform_log2 +#' @export +#' @rdname transform_log +log1p_trans <- transform_log1p + + +#' @rdname transform_log #' @param sigma Scaling factor for the linear part of pseudo-log transformation. #' @export -pseudo_log_trans <- function(sigma = 1, base = exp(1)) { - trans_new( +transform_pseudo_log <- function(sigma = 1, base = exp(1)) { + new_transform( "pseudo_log", function(x) asinh(x / (2 * sigma)) / log(base), function(x) 2 * sigma * sinh(x * log(base)), @@ -324,6 +370,10 @@ pseudo_log_trans <- function(sigma = 1, base = exp(1)) { ) } +#' @export +#' @rdname transform_log +pseudo_log_trans <- transform_pseudo_log + #' Probability transformation #' #' @param distribution probability distribution. Should be standard R @@ -333,14 +383,14 @@ pseudo_log_trans <- function(sigma = 1, base = exp(1)) { #' @param ... other arguments passed on to distribution and quantile functions #' @export #' @examples -#' plot(logit_trans(), xlim = c(0, 1)) -#' plot(probit_trans(), xlim = c(0, 1)) -probability_trans <- function(distribution, ...) { +#' plot(transform_logit(), xlim = c(0, 1)) +#' plot(transform_probit(), xlim = c(0, 1)) +transform_probability <- function(distribution, ...) { qfun <- match.fun(paste0("q", distribution)) pfun <- match.fun(paste0("p", distribution)) dfun <- match.fun(paste0("d", distribution)) - trans_new( + new_transform( paste0("prob-", distribution), function(x) qfun(x, ...), function(x) pfun(x, ...), @@ -349,20 +399,33 @@ probability_trans <- function(distribution, ...) { domain = c(0, 1) ) } + +#' @export +#' @rdname transform_probability +transform_logit <- function() transform_probability("logis") +#' @export +#' @rdname transform_probability +transform_probit <- function() transform_probability("norm") + + +#' @export +#' @rdname transform_probability +probability_trans <- transform_probability #' @export -#' @rdname probability_trans -logit_trans <- function() probability_trans("logis") +#' @rdname transform_probability +logit_trans <- transform_logit #' @export -#' @rdname probability_trans -probit_trans <- function() probability_trans("norm") +#' @rdname transform_probability +probit_trans <- transform_probit + #' Reciprocal transformation #' #' @export #' @examples -#' plot(reciprocal_trans(), xlim = c(0, 1)) -reciprocal_trans <- function() { - trans_new( +#' plot(transform_reciprocal(), xlim = c(0, 1)) +transform_reciprocal <- function() { + new_transform( "reciprocal", function(x) 1 / x, function(x) 1 / x, @@ -371,6 +434,10 @@ reciprocal_trans <- function() { ) } +#' @export +#' @rdname transform_reciprocal +reciprocal_trans <- transform_reciprocal + #' Reverse transformation #' #' reversing transformation works by multiplying the input with -1. This means @@ -379,9 +446,9 @@ reciprocal_trans <- function() { #' #' @export #' @examples -#' plot(reverse_trans(), xlim = c(-1, 1)) -reverse_trans <- function() { - trans_new( +#' plot(transform_reverse(), xlim = c(-1, 1)) +transform_reverse <- function() { + new_transform( "reverse", function(x) -x, function(x) -x, @@ -391,6 +458,10 @@ reverse_trans <- function() { ) } +#' @export +#' @rdname transform_reverse +reverse_trans <- transform_reverse + #' Square-root transformation #' #' This is the variance stabilising transformation for the Poisson @@ -398,9 +469,9 @@ reverse_trans <- function() { #' #' @export #' @examples -#' plot(sqrt_trans(), xlim = c(0, 5)) -sqrt_trans <- function() { - trans_new( +#' plot(transform_sqrt(), xlim = c(0, 5)) +transform_sqrt <- function() { + new_transform( "sqrt", "sqrt", function(x) ifelse(x < 0, NA_real_, x ^ 2), @@ -409,3 +480,7 @@ sqrt_trans <- function() { domain = c(0, Inf) ) } + +#' @export +#' @rdname transform_sqrt +sqrt_trans <- transform_sqrt diff --git a/R/trans.R b/R/transform.R similarity index 68% rename from R/trans.R rename to R/transform.R index 38e43b69..d6da0e74 100644 --- a/R/trans.R +++ b/R/transform.R @@ -24,15 +24,15 @@ #' @param domain the allowed range of the data to be transformed. The function #' in the `transform` argument is expected to be able to transform the `domain` #' argument. -#' @seealso \Sexpr[results=rd,stage=build]{scales:::seealso_trans()} +#' @seealso \Sexpr[results=rd,stage=build]{scales:::seealso_transform()} #' @export #' @keywords internal #' @aliases trans -trans_new <- function(name, transform, inverse, - d_transform = NULL, d_inverse = NULL, - breaks = extended_breaks(), - minor_breaks = regular_minor_breaks(), - format = format_format(), domain = c(-Inf, Inf)) { +new_transform <- function(name, transform, inverse, + d_transform = NULL, d_inverse = NULL, + breaks = extended_breaks(), + minor_breaks = regular_minor_breaks(), + format = format_format(), domain = c(-Inf, Inf)) { if (is.character(transform)) transform <- match.fun(transform) if (is.character(inverse)) inverse <- match.fun(inverse) if (is.character(d_transform)) d_transform <- match.fun(d_transform) @@ -50,22 +50,30 @@ trans_new <- function(name, transform, inverse, format = format, domain = domain ), - class = "trans" + class = "transform" ) } -#' @rdname trans_new +#' @rdname new_transform #' @export -is.trans <- function(x) inherits(x, "trans") +trans_new <- new_transform +#' @rdname new_transform #' @export -print.trans <- function(x, ...) { +is.transform <- function(x) inherits(x, "transform") + +#' @export +#' @rdname new_transform +is.trans <- is.transform + +#' @export +print.transform <- function(x, ...) { cat("Transformer: ", x$name, " [", x$domain[[1]], ", ", x$domain[[2]], "]\n", sep = "") invisible(x) } #' @export -plot.trans <- function(x, y, ..., xlim, ylim = NULL) { +plot.transform <- function(x, y, ..., xlim, ylim = NULL) { if (is.null(ylim)) { ylim <- range(x$transform(seq(xlim[1], xlim[2], length = 100)), finite = TRUE) } @@ -84,40 +92,55 @@ plot.trans <- function(x, y, ..., xlim, ylim = NULL) { } #' @export -lines.trans <- function(x, ..., xlim) { +lines.transform <- function(x, ..., xlim) { xgrid <- seq(xlim[1], xlim[2], length = 100) y <- suppressWarnings(x$transform(xgrid)) graphics::lines(xgrid, y, ...) } -#' @rdname trans_new +#' @rdname new_transform #' @export -as.trans <- function(x, arg = deparse(substitute(x))) { - if (is.trans(x)) { +as.transform <- function(x, arg = deparse(substitute(x))) { + if (is.transform(x)) { x } else if (is.character(x) && length(x) >= 1) { if (length(x) == 1) { - f <- paste0(x, "_trans") + f <- paste0("transform_", x) + # For backward compatibility + if (!exists(f, mode = "function")) { + f2 <- paste0(x, "_trans") + if (exists(f2, mode = "function")) { + f <- f2 + } + } match.fun(f)() } else { - compose_trans(!!!x) + transform_compose(!!!x) } } else { cli::cli_abort(sprintf("{.arg %s} must be a character vector or a transformer object", arg)) } } +#' @export +#' @rdname new_transform +as.trans <- as.transform + #' Compute range of transformed values #' -#' Silently drops any ranges outside of the domain of `trans`. +#' Silently drops any ranges outside of the domain of `transform`. #' -#' @param trans a transformation object, or the name of a transformation object +#' @param transform a transformation object, or the name of a transformation object #' given as a string. #' @param x a numeric vector to compute the range of #' @export #' @keywords internal -trans_range <- function(trans, x) { - trans <- as.trans(trans) - range(trans$transform(range(squish(x, trans$domain), na.rm = TRUE))) +trim_to_domain <- function(transform, x) { + transform <- as.transform(transform) + range(transform$transform(range(squish(x, transform$domain), na.rm = TRUE))) } + +#' @export +#' @rdname trim_to_domain +trans_range <- trim_to_domain diff --git a/README.Rmd b/README.Rmd index cdf373f5..d7d1b6fa 100644 --- a/README.Rmd +++ b/README.Rmd @@ -98,8 +98,8 @@ scales also gives users the ability to define and apply their own custom transformation functions for repeated use. ```{r transforms} -# use trans_new to build a new transformation -logp3_trans <- trans_new( +# use new_transform to build a new transformation +transform_logp3 <- new_transform( name = "logp", transform = function(x) log(x + 3), inverse = function(x) exp(x) - 3, @@ -109,5 +109,5 @@ logp3_trans <- trans_new( dsamp <- sample_n(diamonds, 100) ggplot(dsamp, aes(carat, price, colour = color)) + geom_point() + - scale_y_continuous(trans = logp3_trans) + scale_y_continuous(trans = transform_logp3) ``` diff --git a/README.md b/README.md index 4343bb55..394b3663 100644 --- a/README.md +++ b/README.md @@ -111,8 +111,8 @@ scales also gives users the ability to define and apply their own custom transformation functions for repeated use. ``` r -# use trans_new to build a new transformation -logp3_trans <- trans_new( +# use new_transform to build a new transformation +transform_logp3 <- new_transform( name = "logp", transform = function(x) log(x + 3), inverse = function(x) exp(x) - 3, @@ -122,7 +122,7 @@ logp3_trans <- trans_new( dsamp <- sample_n(diamonds, 100) ggplot(dsamp, aes(carat, price, colour = color)) + geom_point() + - scale_y_continuous(trans = logp3_trans) + scale_y_continuous(trans = transform_logp3) ``` ![](man/figures/README-transforms-1.png) diff --git a/man/cscale.Rd b/man/cscale.Rd index 8783e2c0..2ff6f969 100644 --- a/man/cscale.Rd +++ b/man/cscale.Rd @@ -4,7 +4,7 @@ \alias{cscale} \title{Continuous scale} \usage{ -cscale(x, palette, na.value = NA_real_, trans = identity_trans()) +cscale(x, palette, na.value = NA_real_, trans = transform_identity()) } \arguments{ \item{x}{vector of continuous values to scale} @@ -21,7 +21,7 @@ raw data prior to scaling. Defaults to the identity transformation which leaves the data unchanged. Built in transformations: -\Sexpr[results=rd,stage=build]{scales:::seealso_trans()}.} +\Sexpr[results=rd,stage=build]{scales:::seealso_transform()}.} } \description{ Continuous scale @@ -29,7 +29,7 @@ Continuous scale \examples{ with(mtcars, plot(disp, mpg, cex = cscale(hp, pal_rescale()))) with(mtcars, plot(disp, mpg, cex = cscale(hp, pal_rescale(), - trans = sqrt_trans() + trans = transform_sqrt() ))) with(mtcars, plot(disp, mpg, cex = cscale(hp, pal_area()))) with(mtcars, plot(disp, mpg, diff --git a/man/log_trans.Rd b/man/log_trans.Rd deleted file mode 100644 index 2e6619c6..00000000 --- a/man/log_trans.Rd +++ /dev/null @@ -1,48 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/trans-numeric.R -\name{log_trans} -\alias{log_trans} -\alias{log10_trans} -\alias{log2_trans} -\alias{log1p_trans} -\alias{pseudo_log_trans} -\title{Log transformations} -\usage{ -log_trans(base = exp(1)) - -log10_trans() - -log2_trans() - -log1p_trans() - -pseudo_log_trans(sigma = 1, base = exp(1)) -} -\arguments{ -\item{base}{base of logarithm} - -\item{sigma}{Scaling factor for the linear part of pseudo-log transformation.} -} -\description{ -\itemize{ -\item \code{log_trans()}: \code{log(x)} -\item \code{log1p()}: \code{log(x + 1)} -\item \code{pseudo_log_trans()}: smoothly transition to linear scale around 0. -} -} -\examples{ -plot(log2_trans(), xlim = c(0, 5)) -plot(log_trans(), xlim = c(0, 5)) -plot(log10_trans(), xlim = c(0, 5)) - -plot(log_trans(), xlim = c(0, 2)) -plot(log1p_trans(), xlim = c(-1, 1)) - -# The pseudo-log is defined for all real numbers -plot(pseudo_log_trans(), xlim = c(-5, 5)) -lines(log_trans(), xlim = c(0, 5), col = "red") - -# For large positives nubmers it's very close to log -plot(pseudo_log_trans(), xlim = c(1, 20)) -lines(log_trans(), xlim = c(1, 20), col = "red") -} diff --git a/man/trans_new.Rd b/man/new_transform.Rd similarity index 80% rename from man/trans_new.Rd rename to man/new_transform.Rd index 64ae23ad..b8cc7af6 100644 --- a/man/trans_new.Rd +++ b/man/new_transform.Rd @@ -1,12 +1,27 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in R/trans.R -\name{trans_new} -\alias{trans_new} +% Please edit documentation in R/transform.R +\name{new_transform} +\alias{new_transform} \alias{trans} +\alias{trans_new} +\alias{is.transform} \alias{is.trans} +\alias{as.transform} \alias{as.trans} \title{Create a new transformation object} \usage{ +new_transform( + name, + transform, + inverse, + d_transform = NULL, + d_inverse = NULL, + breaks = extended_breaks(), + minor_breaks = regular_minor_breaks(), + format = format_format(), + domain = c(-Inf, Inf) +) + trans_new( name, transform, @@ -19,8 +34,12 @@ trans_new( domain = c(-Inf, Inf) ) +is.transform(x) + is.trans(x) +as.transform(x, arg = deparse(substitute(x))) + as.trans(x, arg = deparse(substitute(x))) } \arguments{ @@ -59,6 +78,6 @@ well-formatted labels. Transformations may also include the derivatives of the transformation and its inverse, but are not required to. } \seealso{ -\Sexpr[results=rd,stage=build]{scales:::seealso_trans()} +\Sexpr[results=rd,stage=build]{scales:::seealso_transform()} } \keyword{internal} diff --git a/man/pal_shape.Rd b/man/pal_shape.Rd index 367e576e..32f9213a 100644 --- a/man/pal_shape.Rd +++ b/man/pal_shape.Rd @@ -1,5 +1,5 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in R/pal-shape.R +% Please edit documentation in R/pal-shape.r \name{pal_shape} \alias{pal_shape} \alias{shape_pal} diff --git a/man/trans_range.Rd b/man/trans_range.Rd deleted file mode 100644 index 14363080..00000000 --- a/man/trans_range.Rd +++ /dev/null @@ -1,18 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/trans.R -\name{trans_range} -\alias{trans_range} -\title{Compute range of transformed values} -\usage{ -trans_range(trans, x) -} -\arguments{ -\item{trans}{a transformation object, or the name of a transformation object -given as a string.} - -\item{x}{a numeric vector to compute the range of} -} -\description{ -Silently drops any ranges outside of the domain of \code{trans}. -} -\keyword{internal} diff --git a/man/asinh_trans.Rd b/man/transform_asinh.Rd similarity index 55% rename from man/asinh_trans.Rd rename to man/transform_asinh.Rd index 10b4e8be..84fd3cae 100644 --- a/man/asinh_trans.Rd +++ b/man/transform_asinh.Rd @@ -1,14 +1,17 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in R/trans-numeric.R -\name{asinh_trans} +% Please edit documentation in R/transform-numeric.R +\name{transform_asinh} +\alias{transform_asinh} \alias{asinh_trans} \title{Inverse Hyperbolic Sine transformation} \usage{ +transform_asinh() + asinh_trans() } \description{ Inverse Hyperbolic Sine transformation } \examples{ -plot(asinh_trans(), xlim = c(-1e2, 1e2)) +plot(transform_asinh(), xlim = c(-1e2, 1e2)) } diff --git a/man/asn_trans.Rd b/man/transform_asn.Rd similarity index 60% rename from man/asn_trans.Rd rename to man/transform_asn.Rd index 8785c6b0..a08d97d4 100644 --- a/man/asn_trans.Rd +++ b/man/transform_asn.Rd @@ -1,9 +1,12 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in R/trans-numeric.R -\name{asn_trans} +% Please edit documentation in R/transform-numeric.R +\name{transform_asn} +\alias{transform_asn} \alias{asn_trans} \title{Arc-sin square root transformation} \usage{ +transform_asn() + asn_trans() } \description{ @@ -11,5 +14,5 @@ This is the variance stabilising transformation for the binomial distribution. } \examples{ -plot(asn_trans(), xlim = c(0, 1)) +plot(transform_asn(), xlim = c(0, 1)) } diff --git a/man/atanh_trans.Rd b/man/transform_atanh.Rd similarity index 52% rename from man/atanh_trans.Rd rename to man/transform_atanh.Rd index a0b9b78c..6aa99466 100644 --- a/man/atanh_trans.Rd +++ b/man/transform_atanh.Rd @@ -1,14 +1,17 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in R/trans-numeric.R -\name{atanh_trans} +% Please edit documentation in R/transform-numeric.R +\name{transform_atanh} +\alias{transform_atanh} \alias{atanh_trans} \title{Arc-tangent transformation} \usage{ +transform_atanh() + atanh_trans() } \description{ Arc-tangent transformation } \examples{ -plot(atanh_trans(), xlim = c(-1, 1)) +plot(transform_atanh(), xlim = c(-1, 1)) } diff --git a/man/boxcox_trans.Rd b/man/transform_boxcox.Rd similarity index 70% rename from man/boxcox_trans.Rd rename to man/transform_boxcox.Rd index eed1d071..cc6d8ea5 100644 --- a/man/boxcox_trans.Rd +++ b/man/transform_boxcox.Rd @@ -1,19 +1,25 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in R/trans-numeric.R -\name{boxcox_trans} +% Please edit documentation in R/transform-numeric.R +\name{transform_boxcox} +\alias{transform_boxcox} \alias{boxcox_trans} +\alias{transform_modulus} \alias{modulus_trans} \title{Box-Cox & modulus transformations} \usage{ +transform_boxcox(p, offset = 0) + boxcox_trans(p, offset = 0) +transform_modulus(p, offset = 1) + modulus_trans(p, offset = 1) } \arguments{ \item{p}{Transformation exponent, \eqn{\lambda}.} \item{offset}{Constant offset. 0 for Box-Cox type 1, -otherwise any non-negative constant (Box-Cox type 2). \code{modulus_trans()} +otherwise any non-negative constant (Box-Cox type 2). \code{transform_modulus()} sets the default to 1.} } \description{ @@ -36,15 +42,15 @@ and when \code{y = 0}: \deqn{y^{(\lambda)} = sign(y) * \ln(|y| + 1)}{ y^(\lambda) = sign(y) * ln(|y| + 1)} } \examples{ -plot(boxcox_trans(-1), xlim = c(0, 10)) -plot(boxcox_trans(0), xlim = c(0, 10)) -plot(boxcox_trans(1), xlim = c(0, 10)) -plot(boxcox_trans(2), xlim = c(0, 10)) +plot(transform_boxcox(-1), xlim = c(0, 10)) +plot(transform_boxcox(0), xlim = c(0, 10)) +plot(transform_boxcox(1), xlim = c(0, 10)) +plot(transform_boxcox(2), xlim = c(0, 10)) -plot(modulus_trans(-1), xlim = c(-10, 10)) -plot(modulus_trans(0), xlim = c(-10, 10)) -plot(modulus_trans(1), xlim = c(-10, 10)) -plot(modulus_trans(2), xlim = c(-10, 10)) +plot(transform_modulus(-1), xlim = c(-10, 10)) +plot(transform_modulus(0), xlim = c(-10, 10)) +plot(transform_modulus(1), xlim = c(-10, 10)) +plot(transform_modulus(2), xlim = c(-10, 10)) } \references{ Box, G. E., & Cox, D. R. (1964). An analysis of transformations. @@ -56,5 +62,5 @@ An alternative family of transformations. Applied Statistics, 190-197. \url{https://www.jstor.org/stable/2986305} } \seealso{ -\code{\link[=yj_trans]{yj_trans()}} +\code{\link[=transform_yj]{transform_yj()}} } diff --git a/man/compose_trans.Rd b/man/transform_compose.Rd similarity index 82% rename from man/compose_trans.Rd rename to man/transform_compose.Rd index 4af20e58..84dc4ad6 100644 --- a/man/compose_trans.Rd +++ b/man/transform_compose.Rd @@ -1,9 +1,12 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in R/trans-compose.R -\name{compose_trans} +% Please edit documentation in R/transform-compose.R +\name{transform_compose} +\alias{transform_compose} \alias{compose_trans} \title{Compose two or more transformations together} \usage{ +transform_compose(...) + compose_trans(...) } \arguments{ diff --git a/man/date_trans.Rd b/man/transform_date.Rd similarity index 71% rename from man/date_trans.Rd rename to man/transform_date.Rd index 6c110199..85b700f9 100644 --- a/man/date_trans.Rd +++ b/man/transform_date.Rd @@ -1,9 +1,12 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in R/trans-date.R -\name{date_trans} +% Please edit documentation in R/transform-date.R +\name{transform_date} +\alias{transform_date} \alias{date_trans} \title{Transformation for dates (class Date)} \usage{ +transform_date() + date_trans() } \description{ @@ -11,7 +14,7 @@ Transformation for dates (class Date) } \examples{ years <- seq(as.Date("1910/1/1"), as.Date("1999/1/1"), "years") -t <- date_trans() +t <- transform_date() t$transform(years) t$inverse(t$transform(years)) t$format(t$breaks(range(years))) diff --git a/man/exp_trans.Rd b/man/transform_exp.Rd similarity index 50% rename from man/exp_trans.Rd rename to man/transform_exp.Rd index 92f5b9e5..b1addd90 100644 --- a/man/exp_trans.Rd +++ b/man/transform_exp.Rd @@ -1,9 +1,12 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in R/trans-numeric.R -\name{exp_trans} +% Please edit documentation in R/transform-numeric.R +\name{transform_exp} +\alias{transform_exp} \alias{exp_trans} \title{Exponential transformation (inverse of log transformation)} \usage{ +transform_exp(base = exp(1)) + exp_trans(base = exp(1)) } \arguments{ @@ -13,8 +16,8 @@ exp_trans(base = exp(1)) Exponential transformation (inverse of log transformation) } \examples{ -plot(exp_trans(0.5), xlim = c(-2, 2)) -plot(exp_trans(1), xlim = c(-2, 2)) -plot(exp_trans(2), xlim = c(-2, 2)) -plot(exp_trans(), xlim = c(-2, 2)) +plot(transform_exp(0.5), xlim = c(-2, 2)) +plot(transform_exp(1), xlim = c(-2, 2)) +plot(transform_exp(2), xlim = c(-2, 2)) +plot(transform_exp(), xlim = c(-2, 2)) } diff --git a/man/identity_trans.Rd b/man/transform_identity.Rd similarity index 54% rename from man/identity_trans.Rd rename to man/transform_identity.Rd index efb88769..f5a22f5b 100644 --- a/man/identity_trans.Rd +++ b/man/transform_identity.Rd @@ -1,14 +1,17 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in R/trans-numeric.R -\name{identity_trans} +% Please edit documentation in R/transform-numeric.R +\name{transform_identity} +\alias{transform_identity} \alias{identity_trans} \title{Identity transformation (do nothing)} \usage{ +transform_identity() + identity_trans() } \description{ Identity transformation (do nothing) } \examples{ -plot(identity_trans(), xlim = c(-1, 1)) +plot(transform_identity(), xlim = c(-1, 1)) } diff --git a/man/transform_log.Rd b/man/transform_log.Rd new file mode 100644 index 00000000..ad0a18e1 --- /dev/null +++ b/man/transform_log.Rd @@ -0,0 +1,63 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/transform-numeric.R +\name{transform_log} +\alias{transform_log} +\alias{transform_log10} +\alias{transform_log2} +\alias{transform_log1p} +\alias{log_trans} +\alias{log10_trans} +\alias{log2_trans} +\alias{log1p_trans} +\alias{transform_pseudo_log} +\alias{pseudo_log_trans} +\title{Log transformations} +\usage{ +transform_log(base = exp(1)) + +transform_log10() + +transform_log2() + +transform_log1p() + +log_trans(base = exp(1)) + +log10_trans() + +log2_trans() + +log1p_trans() + +transform_pseudo_log(sigma = 1, base = exp(1)) + +pseudo_log_trans(sigma = 1, base = exp(1)) +} +\arguments{ +\item{base}{base of logarithm} + +\item{sigma}{Scaling factor for the linear part of pseudo-log transformation.} +} +\description{ +\itemize{ +\item \code{transform_log()}: \code{log(x)} +\item \code{log1p()}: \code{log(x + 1)} +\item \code{transform_pseudo_log()}: smoothly transition to linear scale around 0. +} +} +\examples{ +plot(transform_log2(), xlim = c(0, 5)) +plot(transform_log(), xlim = c(0, 5)) +plot(transform_log10(), xlim = c(0, 5)) + +plot(transform_log(), xlim = c(0, 2)) +plot(transform_log1p(), xlim = c(-1, 1)) + +# The pseudo-log is defined for all real numbers +plot(transform_pseudo_log(), xlim = c(-5, 5)) +lines(transform_log(), xlim = c(0, 5), col = "red") + +# For large positives numbers it's very close to log +plot(transform_pseudo_log(), xlim = c(1, 20)) +lines(transform_log(), xlim = c(1, 20), col = "red") +} diff --git a/man/probability_trans.Rd b/man/transform_probability.Rd similarity index 66% rename from man/probability_trans.Rd rename to man/transform_probability.Rd index e0a4e82d..a1711017 100644 --- a/man/probability_trans.Rd +++ b/man/transform_probability.Rd @@ -1,11 +1,20 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in R/trans-numeric.R -\name{probability_trans} +% Please edit documentation in R/transform-numeric.R +\name{transform_probability} +\alias{transform_probability} +\alias{transform_logit} +\alias{transform_probit} \alias{probability_trans} \alias{logit_trans} \alias{probit_trans} \title{Probability transformation} \usage{ +transform_probability(distribution, ...) + +transform_logit() + +transform_probit() + probability_trans(distribution, ...) logit_trans() @@ -24,6 +33,6 @@ function, "q" + distribution is a valid quantile function, and Probability transformation } \examples{ -plot(logit_trans(), xlim = c(0, 1)) -plot(probit_trans(), xlim = c(0, 1)) +plot(transform_logit(), xlim = c(0, 1)) +plot(transform_probit(), xlim = c(0, 1)) } diff --git a/man/reciprocal_trans.Rd b/man/transform_reciprocal.Rd similarity index 51% rename from man/reciprocal_trans.Rd rename to man/transform_reciprocal.Rd index aec21d60..9de217b7 100644 --- a/man/reciprocal_trans.Rd +++ b/man/transform_reciprocal.Rd @@ -1,14 +1,17 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in R/trans-numeric.R -\name{reciprocal_trans} +% Please edit documentation in R/transform-numeric.R +\name{transform_reciprocal} +\alias{transform_reciprocal} \alias{reciprocal_trans} \title{Reciprocal transformation} \usage{ +transform_reciprocal() + reciprocal_trans() } \description{ Reciprocal transformation } \examples{ -plot(reciprocal_trans(), xlim = c(0, 1)) +plot(transform_reciprocal(), xlim = c(0, 1)) } diff --git a/man/reverse_trans.Rd b/man/transform_reverse.Rd similarity index 69% rename from man/reverse_trans.Rd rename to man/transform_reverse.Rd index 049f5499..8971ec5b 100644 --- a/man/reverse_trans.Rd +++ b/man/transform_reverse.Rd @@ -1,9 +1,12 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in R/trans-numeric.R -\name{reverse_trans} +% Please edit documentation in R/transform-numeric.R +\name{transform_reverse} +\alias{transform_reverse} \alias{reverse_trans} \title{Reverse transformation} \usage{ +transform_reverse() + reverse_trans() } \description{ @@ -12,5 +15,5 @@ that reverse transformation cannot easily be composed with transformations that require positive input unless the reversing is done as a final step. } \examples{ -plot(reverse_trans(), xlim = c(-1, 1)) +plot(transform_reverse(), xlim = c(-1, 1)) } diff --git a/man/sqrt_trans.Rd b/man/transform_sqrt.Rd similarity index 59% rename from man/sqrt_trans.Rd rename to man/transform_sqrt.Rd index f2695747..2478faf3 100644 --- a/man/sqrt_trans.Rd +++ b/man/transform_sqrt.Rd @@ -1,9 +1,12 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in R/trans-numeric.R -\name{sqrt_trans} +% Please edit documentation in R/transform-numeric.R +\name{transform_sqrt} +\alias{transform_sqrt} \alias{sqrt_trans} \title{Square-root transformation} \usage{ +transform_sqrt() + sqrt_trans() } \description{ @@ -11,5 +14,5 @@ This is the variance stabilising transformation for the Poisson distribution. } \examples{ -plot(sqrt_trans(), xlim = c(0, 5)) +plot(transform_sqrt(), xlim = c(0, 5)) } diff --git a/man/time_trans.Rd b/man/transform_time.Rd similarity index 78% rename from man/time_trans.Rd rename to man/transform_time.Rd index 8b473327..b82c12d0 100644 --- a/man/time_trans.Rd +++ b/man/transform_time.Rd @@ -1,9 +1,12 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in R/trans-date.R -\name{time_trans} +% Please edit documentation in R/transform-date.R +\name{transform_time} +\alias{transform_time} \alias{time_trans} \title{Transformation for date-times (class POSIXt)} \usage{ +transform_time(tz = NULL) + time_trans(tz = NULL) } \arguments{ @@ -15,7 +18,7 @@ Transformation for date-times (class POSIXt) } \examples{ hours <- seq(ISOdate(2000, 3, 20, tz = ""), by = "hour", length.out = 10) -t <- time_trans() +t <- transform_time() t$transform(hours) t$inverse(t$transform(hours)) t$format(t$breaks(range(hours))) diff --git a/man/timespan_trans.Rd b/man/transform_timespan.Rd similarity index 53% rename from man/timespan_trans.Rd rename to man/transform_timespan.Rd index 6ead6f0d..18eb8bae 100644 --- a/man/timespan_trans.Rd +++ b/man/transform_timespan.Rd @@ -1,35 +1,41 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in R/trans-date.R -\name{timespan_trans} +% Please edit documentation in R/transform-date.R +\name{transform_timespan} +\alias{transform_timespan} \alias{timespan_trans} +\alias{transform_hms} \alias{hms_trans} \title{Transformation for times (class hms)} \usage{ +transform_timespan(unit = c("secs", "mins", "hours", "days", "weeks")) + timespan_trans(unit = c("secs", "mins", "hours", "days", "weeks")) +transform_hms() + hms_trans() } \arguments{ \item{unit}{The unit used to interpret numeric input} } \description{ -\code{timespan_trans()} provides transformations for data encoding time passed +\code{transform_timespan()} provides transformations for data encoding time passed along with breaks and label formatting showing standard unit of time fitting -the range of the data. \code{hms_trans()} provides the same but using standard hms -idioms and formatting. +the range of the data. \code{transform_hms()} provides the same but using standard +hms idioms and formatting. } \examples{ -# timespan_trans allows you to specify the time unit numeric data is +# transform_timespan allows you to specify the time unit numeric data is # interpreted in -min_trans <- timespan_trans("mins") -demo_timespan(seq(0, 100), trans = min_trans) +trans_min <- transform_timespan("mins") +demo_timespan(seq(0, 100), trans = trans_min) # Input already in difftime format is interpreted correctly -demo_timespan(as.difftime(seq(0, 100), units = "secs"), trans = min_trans) +demo_timespan(as.difftime(seq(0, 100), units = "secs"), trans = trans_min) if (require("hms")) { - # hms_trans always assumes seconds + # transform_hms always assumes seconds hms <- round(runif(10) * 86400) - t <- hms_trans() + t <- transform_hms() t$transform(hms) t$inverse(t$transform(hms)) t$breaks(hms) diff --git a/man/yj_trans.Rd b/man/transform_yj.Rd similarity index 73% rename from man/yj_trans.Rd rename to man/transform_yj.Rd index f129e416..0eae8a30 100644 --- a/man/yj_trans.Rd +++ b/man/transform_yj.Rd @@ -1,18 +1,21 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in R/trans-numeric.R -\name{yj_trans} +% Please edit documentation in R/transform-numeric.R +\name{transform_yj} +\alias{transform_yj} \alias{yj_trans} \title{Yeo-Johnson transformation} \usage{ +transform_yj(p) + yj_trans(p) } \arguments{ \item{p}{Transformation exponent, \eqn{\lambda}.} } \description{ -The Yeo-Johnson transformation is a flexible transformation that is similiar -to Box-Cox, \code{\link[=boxcox_trans]{boxcox_trans()}}, but does not require input values to be greater -than zero. +The Yeo-Johnson transformation is a flexible transformation that is similar +to Box-Cox, \code{\link[=transform_boxcox]{transform_boxcox()}}, but does not require input values to be +greater than zero. } \details{ The transformation takes one of four forms depending on the values of \code{y} and \eqn{\lambda}. @@ -28,10 +31,10 @@ The transformation takes one of four forms depending on the values of \code{y} a } } \examples{ -plot(yj_trans(-1), xlim = c(-10, 10)) -plot(yj_trans(0), xlim = c(-10, 10)) -plot(yj_trans(1), xlim = c(-10, 10)) -plot(yj_trans(2), xlim = c(-10, 10)) +plot(transform_yj(-1), xlim = c(-10, 10)) +plot(transform_yj(0), xlim = c(-10, 10)) +plot(transform_yj(1), xlim = c(-10, 10)) +plot(transform_yj(2), xlim = c(-10, 10)) } \references{ Yeo, I., & Johnson, R. (2000). diff --git a/man/trim_to_domain.Rd b/man/trim_to_domain.Rd new file mode 100644 index 00000000..fa224c55 --- /dev/null +++ b/man/trim_to_domain.Rd @@ -0,0 +1,21 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/transform.R +\name{trim_to_domain} +\alias{trim_to_domain} +\alias{trans_range} +\title{Compute range of transformed values} +\usage{ +trim_to_domain(transform, x) + +trans_range(transform, x) +} +\arguments{ +\item{transform}{a transformation object, or the name of a transformation object +given as a string.} + +\item{x}{a numeric vector to compute the range of} +} +\description{ +Silently drops any ranges outside of the domain of \code{transform}. +} +\keyword{internal} diff --git a/tests/testthat/_snaps/trans-compose.md b/tests/testthat/_snaps/trans-compose.md index 6eafb963..c2f772a1 100755 --- a/tests/testthat/_snaps/trans-compose.md +++ b/tests/testthat/_snaps/trans-compose.md @@ -1,13 +1,13 @@ # produces informative errors Code - compose_trans() + transform_compose() Condition - Error in `compose_trans()`: - ! `compose_trans()` must include at least 1 transformer to compose + Error in `transform_compose()`: + ! `transform_compose()` must include at least 1 transformer to compose Code - compose_trans("sqrt", "reverse", "log10") + transform_compose("sqrt", "reverse", "log10") Condition - Error in `compose_trans()`: + Error in `transform_compose()`: ! Sequence of transformations yields invalid domain diff --git a/tests/testthat/_snaps/trans-date.md b/tests/testthat/_snaps/trans-date.md index ff41bec3..bb644fbf 100644 --- a/tests/testthat/_snaps/trans-date.md +++ b/tests/testthat/_snaps/trans-date.md @@ -1,8 +1,8 @@ # date/time scales raise error on incorrect inputs - `time_trans()` works with objects of class only + `transform_time()` works with objects of class only --- - `date_trans()` works with objects of class only + `transform_date()` works with objects of class only diff --git a/tests/testthat/_snaps/trans.md b/tests/testthat/_snaps/trans.md index e5b33823..a2304d14 100644 --- a/tests/testthat/_snaps/trans.md +++ b/tests/testthat/_snaps/trans.md @@ -1,20 +1,20 @@ -# as.trans generates informative error +# as.transform generates informative error Code - as.trans(1) + as.transform(1) Condition - Error in `as.trans()`: + Error in `as.transform()`: ! `1` must be a character vector or a transformer object Code - as.trans("x") + as.transform("x") Condition Error in `get()`: - ! object 'x_trans' of mode 'function' was not found + ! object 'transform_x' of mode 'function' was not found # trans has useful print method Code - trans_new("test", transform = identity, inverse = identity) + new_transform("test", transform = identity, inverse = identity) Output Transformer: test [-Inf, Inf] diff --git a/tests/testthat/test-trans-compose.R b/tests/testthat/test-trans-compose.R index 314b735e..06a95d9f 100644 --- a/tests/testthat/test-trans-compose.R +++ b/tests/testthat/test-trans-compose.R @@ -1,38 +1,38 @@ test_that("composes transforms correctly", { - t <- compose_trans("log10", "reverse") + t <- transform_compose("log10", "reverse") expect_equal(t$transform(100), -2) expect_equal(t$inverse(-2), 100) }) test_that("composes derivatives correctly", { - t <- compose_trans("sqrt", "reciprocal", "reverse") + t <- transform_compose("sqrt", "reciprocal", "reverse") expect_equal(t$d_transform(0.25), 4) expect_equal(t$d_inverse(-2), 0.25) }) test_that("produces NULL derivatives if not all transforms have derivatives", { - t <- compose_trans("sqrt", trans_new("no_deriv", identity, identity)) + t <- transform_compose("sqrt", new_transform("no_deriv", identity, identity)) expect_null(t$d_transform) expect_null(t$d_inverse) }) test_that("uses breaks from first transformer", { - t <- compose_trans("log10", "reverse") + t <- transform_compose("log10", "reverse") expect_equal(t$breaks(c(1, 1000)), log_breaks()(c(1, 1000))) }) test_that("produces informative errors", { expect_snapshot(error = TRUE, { - compose_trans() - compose_trans("sqrt", "reverse", "log10") + transform_compose() + transform_compose("sqrt", "reverse", "log10") }) }) test_that("produces correct domains", { - expect_equal(compose_trans("sqrt", "reverse")$domain, c(0, Inf)) - expect_equal(compose_trans("sqrt", "log")$domain, c(0, Inf)) - expect_equal(compose_trans("log", "log")$domain, c(1, Inf)) - expect_equal(compose_trans("reverse", "log")$domain, c(-Inf, 0)) - expect_equal(compose_trans("reverse", "logit", "log")$domain, c(-1, -0.5)) - expect_error(compose_trans("sqrt", "reverse", "log")$domain, "invalid domain") + expect_equal(transform_compose("sqrt", "reverse")$domain, c(0, Inf)) + expect_equal(transform_compose("sqrt", "log")$domain, c(0, Inf)) + expect_equal(transform_compose("log", "log")$domain, c(1, Inf)) + expect_equal(transform_compose("reverse", "log")$domain, c(-Inf, 0)) + expect_equal(transform_compose("reverse", "logit", "log")$domain, c(-1, -0.5)) + expect_error(transform_compose("sqrt", "reverse", "log")$domain, "invalid domain") }) diff --git a/tests/testthat/test-trans-date.R b/tests/testthat/test-trans-date.R index 38092367..5516ed57 100644 --- a/tests/testthat/test-trans-date.R +++ b/tests/testthat/test-trans-date.R @@ -9,22 +9,22 @@ with_tz <- function(x, value) { } test_that("date/time scales raise error on incorrect inputs", { - time <- time_trans() + time <- transform_time() expect_snapshot_error(time$transform(a_date)) - date <- date_trans() + date <- transform_date() expect_snapshot_error(date$transform(a_time)) }) test_that("time scales learn timezones", { skip_if_not(getRversion() > "3.3.3") - time <- time_trans() + time <- transform_time() x <- time$inverse(time$transform(a_time)) expect_equal(tz(x), "UTC") expect_equal(tz2(x), "UTC") - time <- time_trans() + time <- transform_time() x <- time$inverse(time$transform(with_tz(a_time, "GMT"))) expect_equal(tz(x), "GMT") @@ -32,7 +32,7 @@ test_that("time scales learn timezones", { }) test_that("tz arugment overrules default time zone", { - time <- time_trans("GMT") + time <- transform_time("GMT") x <- time$inverse(time$transform(a_time)) expect_equal(tz(x), "GMT") @@ -59,9 +59,9 @@ test_that("date_breaks() works", { }) test_that("can invert domain", { - t <- date_trans() + t <- transform_date() expect_equal(t$transform(t$domain), c(-Inf, Inf)) - t <- time_trans() + t <- transform_time() expect_equal(t$transform(t$domain), c(-Inf, Inf)) }) diff --git a/tests/testthat/test-trans-numeric.R b/tests/testthat/test-trans-numeric.R index a7f5cbf8..ff3523bc 100644 --- a/tests/testthat/test-trans-numeric.R +++ b/tests/testthat/test-trans-numeric.R @@ -1,5 +1,5 @@ test_that("Pseudo-log is invertible", { - trans <- pseudo_log_trans() + trans <- transform_pseudo_log() expect_equal( trans$inverse(trans$transform(-10:10)), -10:10 @@ -7,63 +7,63 @@ test_that("Pseudo-log is invertible", { }) test_that("Modulus is invertible for negative and positive numbers", { - trans <- modulus_trans(p = .1) + trans <- transform_modulus(p = .1) expect_equal(trans$inv(trans$trans(-10:10)), -10:10) - trans <- modulus_trans(p = -2) + trans <- transform_modulus(p = -2) expect_equal(trans$inv(trans$trans(-10:10)), -10:10) - trans <- modulus_trans(p = 1) + trans <- transform_modulus(p = 1) expect_equal(trans$inv(trans$trans(-10:10)), -10:10) }) test_that("Boxcox gives error for negative values", { - trans <- boxcox_trans(p = .1) + trans <- transform_boxcox(p = .1) expect_error(trans$trans(-10:10)) - trans <- boxcox_trans(p = -2) + trans <- transform_boxcox(p = -2) expect_error(trans$trans(-10:10)) }) test_that("Boxcox can handle NA values", { - trans <- boxcox_trans(p = 0) + trans <- transform_boxcox(p = 0) expect_equal(trans$trans(c(1, NA_real_)), c(0, NA_real_)) }) test_that("Boxcox is invertible", { - trans <- boxcox_trans(p = .1) + trans <- transform_boxcox(p = .1) expect_equal(trans$inv(trans$trans(0:10)), 0:10) - trans <- boxcox_trans(p = -2) + trans <- transform_boxcox(p = -2) expect_equal(trans$inv(trans$trans(0:10)), 0:10) - trans <- boxcox_trans(p = 1) + trans <- transform_boxcox(p = 1) expect_equal(trans$inv(trans$trans(0:10)), 0:10) }) test_that("Yeo-Johnson is invertible", { x <- c(-12345, 12345, -0.12345, 0.12345, -10:10) - trans <- yj_trans(p = -1.5) + trans <- transform_yj(p = -1.5) expect_equal(trans$inverse(trans$transform(x)), x) - trans <- yj_trans(p = 0) + trans <- transform_yj(p = 0) expect_equal(trans$inverse(trans$transform(x)), x) - trans <- yj_trans(p = 0.7) + trans <- transform_yj(p = 0.7) expect_equal(trans$inverse(trans$transform(x)), x) - trans <- yj_trans(p = 1.5) + trans <- transform_yj(p = 1.5) expect_equal(trans$inverse(trans$transform(x)), x) - trans <- yj_trans(p = 2) + trans <- transform_yj(p = 2) expect_equal(trans$inverse(trans$transform(x)), x) }) test_that("Yeo-Johnson is identity function for p = 1", { x <- c(-12345, 12345, -0.12345, 0.12345, -10:10) - trans <- yj_trans(p = 1) + trans <- transform_yj(p = 1) expect_equal(trans$transform(x), x) }) test_that("Yeo-Johnson transforms NAs to NAs without error", { x <- c(1, 2, NA, 4) - trans <- yj_trans(p = 1) + trans <- transform_yj(p = 1) expect_equal(trans$transform(x), x) }) @@ -112,20 +112,20 @@ test_that("Yeo-Johnson transform works", { ) ) - expect_equal(yj_trans(lambdas[1])$transform(x[[1]]), expected_data[[1]]) - expect_equal(yj_trans(lambdas[2])$transform(x[[2]]), expected_data[[2]]) - expect_equal(yj_trans(lambdas[3])$transform(x[[3]]), expected_data[[3]]) + expect_equal(transform_yj(lambdas[1])$transform(x[[1]]), expected_data[[1]]) + expect_equal(transform_yj(lambdas[2])$transform(x[[2]]), expected_data[[2]]) + expect_equal(transform_yj(lambdas[3])$transform(x[[3]]), expected_data[[3]]) }) test_that("probability transforms have domain (0,1)", { - expect_equal(logit_trans()$domain, c(0, 1)) - expect_equal(probit_trans()$domain, c(0, 1)) + expect_equal(transform_logit()$domain, c(0, 1)) + expect_equal(transform_probit()$domain, c(0, 1)) }) # Derivatives ------------------------------------------------------------- -test_that("asn_trans derivatives work", { - trans <- asn_trans() +test_that("transform_asn derivatives work", { + trans <- transform_asn() expect_equal(trans$d_transform(c(0, 0.5, 1)), c(Inf, 2, Inf)) expect_equal(trans$d_inverse(c(0, pi/2, pi)), c(0, 0.5, 0)) x <- seq(0.1, 0.9, length.out = 10) @@ -133,8 +133,8 @@ test_that("asn_trans derivatives work", { expect_equal(trans$d_inverse(x), 1 / trans$d_transform(trans$inverse(x))) }) -test_that("atanh_trans derivatives work", { - trans <- atanh_trans() +test_that("transform_atanh derivatives work", { + trans <- transform_atanh() expect_equal(trans$d_transform(c(-1, 0, 1)), c(Inf, 1, Inf)) expect_equal(trans$d_inverse(c(-log(2), 0, log(2))), c(0.64, 1, 0.64)) x <- seq(-0.9, 0.9, length.out = 10) @@ -142,8 +142,8 @@ test_that("atanh_trans derivatives work", { expect_equal(trans$d_inverse(x), 1 / trans$d_transform(trans$inverse(x))) }) -test_that("asinh_trans derivatives work", { - trans <- asinh_trans() +test_that("transform_asinh derivatives work", { + trans <- transform_asinh() expect_equal(trans$d_transform(c(-1, 0, 1)), c(sqrt(2) / 2, 1, sqrt(2) / 2)) expect_equal(trans$d_inverse(c(-log(2), 0, log(2))), c(1.25, 1, 1.25)) x <- seq(-0.9, 0.9, length.out = 10) @@ -151,53 +151,53 @@ test_that("asinh_trans derivatives work", { expect_equal(trans$d_inverse(x), 1 / trans$d_transform(trans$inverse(x))) }) -test_that("boxcox_trans derivatives work", { - trans <- boxcox_trans(p = 0, offset = 1) +test_that("transform_boxcox derivatives work", { + trans <- transform_boxcox(p = 0, offset = 1) expect_equal(trans$d_transform(c(0, 1, 2)), c(1, 1/2, 1/3)) expect_equal(trans$d_inverse(c(0, 1, 2)), exp(c(0, 1, 2))) x <- 0:10 expect_equal(trans$d_transform(x), 1 / trans$d_inverse(trans$transform(x))) expect_equal(trans$d_inverse(x), 1 / trans$d_transform(trans$inverse(x))) - trans <- boxcox_trans(p = 2, offset = 2) + trans <- transform_boxcox(p = 2, offset = 2) expect_equal(trans$d_transform(c(0, 1, 2)), c(2, 3, 4)) expect_equal(trans$d_inverse(c(0, 0.5, 4)), c(1, sqrt(2) / 2, 1/3)) expect_equal(trans$d_transform(x), 1 / trans$d_inverse(trans$transform(x))) expect_equal(trans$d_inverse(x), 1 / trans$d_transform(trans$inverse(x))) }) -test_that("modulus_trans derivatives work", { - trans <- modulus_trans(p = 0, offset = 1) +test_that("transform_modulus derivatives work", { + trans <- transform_modulus(p = 0, offset = 1) expect_equal(trans$d_transform(c(-2, -1, 1, 2)), c(1/3, 1/2, 1/2, 1/3)) expect_equal(trans$d_inverse(c(-2, -1, 1, 2)), exp(c(2, 1, 1, 2))) x <- c(-10:-2, 2:10) expect_equal(trans$d_transform(x), 1 / trans$d_inverse(trans$transform(x))) expect_equal(trans$d_inverse(x), 1 / trans$d_transform(trans$inverse(x))) - trans <- modulus_trans(p = 2, offset = 2) + trans <- transform_modulus(p = 2, offset = 2) expect_equal(trans$d_transform(c(-2, -1, 1, 2)), c(4, 3, 3, 4)) expect_equal(trans$d_inverse(c(-4, -0.5, 0.5, 4)), c(1/3, sqrt(2) / 2, sqrt(2) / 2, 1/3)) expect_equal(trans$d_transform(x), 1 / trans$d_inverse(trans$transform(x))) expect_equal(trans$d_inverse(x), 1 / trans$d_transform(trans$inverse(x))) }) -test_that("yj_trans derivatives work", { - trans <- yj_trans(p = 0) +test_that("transform_yj derivatives work", { + trans <- transform_yj(p = 0) expect_equal(trans$d_transform(c(-2, -1, 1, 2)), c(3, 2, 0.5, 1/3)) expect_equal(trans$d_inverse(c(-1/2, 1, 2)), c(sqrt(2) / 2, exp(1), exp(2))) x <- c(-10:10) expect_equal(trans$d_transform(x), 1 / trans$d_inverse(trans$transform(x))) expect_equal(trans$d_inverse(x), 1 / trans$d_transform(trans$inverse(x))) - trans <- yj_trans(p = 3) + trans <- transform_yj(p = 3) expect_equal(trans$d_transform(c(-2, -1, 1, 2)), c(1/9, 1/4, 4, 9)) expect_equal(trans$d_inverse(c(-4, -0.5, 1)), c(1/9, 4, (1/16)^(1/3))) expect_equal(trans$d_transform(x), 1 / trans$d_inverse(trans$transform(x))) expect_equal(trans$d_inverse(0:10), 1 / trans$d_transform(trans$inverse(0:10))) }) -test_that("exp_trans derivatives work", { - trans <- exp_trans(10) +test_that("transform_exp derivatives work", { + trans <- transform_exp(10) expect_equal(trans$d_transform(c(0, 1, 2)), c(1, 10, 100) * log(10)) expect_equal(trans$d_inverse(c(0.1, 1, 10) / log(10)), c(10, 1, 0.1)) x <- 1:10 @@ -205,16 +205,16 @@ test_that("exp_trans derivatives work", { expect_equal(trans$d_inverse(x), 1 / trans$d_transform(trans$inverse(x))) }) -test_that("identity_trans derivatives work", { - trans <- identity_trans() +test_that("transform_identity derivatives work", { + trans <- transform_identity() expect_equal(trans$d_transform(numeric(0)), numeric(0)) expect_equal(trans$d_transform(c(0, 1, 2)), c(1, 1, 1)) expect_equal(trans$d_inverse(numeric(0)), numeric(0)) expect_equal(trans$d_inverse(c(0, 1, 2)), c(1, 1, 1)) }) -test_that("log_trans derivatives work", { - trans <- log_trans(10) +test_that("transform_log derivatives work", { + trans <- transform_log(10) expect_equal(trans$d_transform(c(0.1, 1, 10) / log(10)), c(10, 1, 0.1)) expect_equal(trans$d_inverse(c(0, 1, 2)), c(1, 10, 100) * log(10)) x <- 1:10 @@ -222,8 +222,8 @@ test_that("log_trans derivatives work", { expect_equal(trans$d_inverse(x), 1 / trans$d_transform(trans$inverse(x))) }) -test_that("log1p_trans derivatives work", { - trans <- log1p_trans() +test_that("transform_log1p derivatives work", { + trans <- transform_log1p() expect_equal(trans$d_transform(c(0, 1, 2)), c(1, 1/2, 1/3)) expect_equal(trans$d_inverse(c(0, 1, 2)), exp(c(0, 1, 2))) x <- 0:10 @@ -231,8 +231,8 @@ test_that("log1p_trans derivatives work", { expect_equal(trans$d_inverse(x), 1 / trans$d_transform(trans$inverse(x))) }) -test_that("pseudo_log_trans derivatives work", { - trans <- pseudo_log_trans(0.5) +test_that("transform_pseudo_log derivatives work", { + trans <- transform_pseudo_log(0.5) expect_equal(trans$d_transform(c(0, 1)), c(1, sqrt(2) / 2)) expect_equal(trans$d_inverse(c(0, 1)), c(1, cosh(1))) x <- 1:10 @@ -240,8 +240,8 @@ test_that("pseudo_log_trans derivatives work", { expect_equal(trans$d_inverse(x), 1 / trans$d_transform(trans$inverse(x))) }) -test_that("logit_trans derivatives work", { - trans <- logit_trans() +test_that("transform_logit derivatives work", { + trans <- transform_logit() expect_equal(trans$d_transform(c(0.1, 0.5, 0.8)), c(100/9, 4, 6.25)) expect_equal(trans$d_inverse(c(0, 1, 2)), dlogis(c(0, 1, 2))) x <- seq(0.1, 0.9, length.out = 10) @@ -249,8 +249,8 @@ test_that("logit_trans derivatives work", { expect_equal(trans$d_inverse(x), 1 / trans$d_transform(trans$inverse(x))) }) -test_that("reciprocal_trans derivatives work", { - trans <- reciprocal_trans() +test_that("transform_reciprocal derivatives work", { + trans <- transform_reciprocal() expect_equal(trans$d_transform(c(0.1, 1, 10)), c(-100, -1, -0.01)) expect_equal(trans$d_inverse(c(0.1, 1, 10)), c(-100, -1, -0.01)) x <- (1:20)/10 @@ -258,16 +258,16 @@ test_that("reciprocal_trans derivatives work", { expect_equal(trans$d_inverse(x), 1 / trans$d_transform(trans$inverse(x))) }) -test_that("reverse_trans derivatives work", { - trans <- reverse_trans() +test_that("transform_reverse derivatives work", { + trans <- transform_reverse() expect_equal(trans$d_transform(numeric(0)), numeric(0)) expect_equal(trans$d_transform(c(-1, 1, 2)), c(-1, -1, -1)) expect_equal(trans$d_inverse(numeric(0)), numeric(0)) expect_equal(trans$d_inverse(c(-1, 1, 2)), c(-1, -1, -1)) }) -test_that("sqrt_trans derivatives work", { - trans <- sqrt_trans() +test_that("transform_sqrt derivatives work", { + trans <- transform_sqrt() expect_equal(trans$d_transform(c(1, 4, 9)), c(1/2, 1/4, 1/6)) expect_equal(trans$d_inverse(c(1, 2, 3)), c(2, 4, 6)) x <- 1:10 diff --git a/tests/testthat/test-trans.R b/tests/testthat/test-trans.R index 7030d43f..72fae75a 100644 --- a/tests/testthat/test-trans.R +++ b/tests/testthat/test-trans.R @@ -1,33 +1,33 @@ test_that("Transformed ranges silently drop out-of-domain values", { - r1 <- trans_range(log_trans(), -1:10) + r1 <- trim_to_domain(transform_log(), -1:10) expect_equal(r1, log(c(1e-100, 10))) - r2 <- trans_range(sqrt_trans(), -1:10) + r2 <- trim_to_domain(transform_sqrt(), -1:10) expect_equal(r2, sqrt(c(0, 10))) }) -test_that("as.trans handles character inputs", { - expect_equal(as.trans("log10"), log10_trans()) +test_that("as.transform handles character inputs", { + expect_equal(as.trans("log10"), transform_log10()) expect_equal( - as.trans(c("log10", "reverse")), - compose_trans(log10_trans(), reverse_trans()) + as.transform(c("log10", "reverse")), + transform_compose(transform_log10(), transform_reverse()) ) }) -test_that("as.trans generates informative error", { +test_that("as.transform generates informative error", { expect_snapshot(error = TRUE, { - as.trans(1) - as.trans("x") + as.transform(1) + as.transform("x") }) }) test_that("trans has useful print method", { expect_snapshot({ - trans_new("test", transform = identity, inverse = identity) + new_transform("test", transform = identity, inverse = identity) }) }) test_that("inverse of trans_sqrt() returns NA for values outside of range", { - expect_equal(sqrt_trans()$inverse(-2), NA_real_) + expect_equal(transform_sqrt()$inverse(-2), NA_real_) })