Skip to content

Commit

Permalink
Implement label_log() (#312)
Browse files Browse the repository at this point in the history
Fixes #311
  • Loading branch information
davidchall authored Mar 17, 2022
1 parent ba0d156 commit eb3e544
Show file tree
Hide file tree
Showing 10 changed files with 100 additions and 10 deletions.
1 change: 1 addition & 0 deletions NAMESPACE
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ export(label_comma)
export(label_date)
export(label_date_short)
export(label_dollar)
export(label_log)
export(label_math)
export(label_number)
export(label_number_auto)
Expand Down
3 changes: 3 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,9 @@
* Internal `precision()`, used when `accuracy = NULL`, now avoids displaying
unnecessary digits (@davidchall, #304).

* New `label_log()` displays the base and a superscript exponent, for use with
logarithmic axes (@davidchall, #312).

# scales 1.1.1

* `breaks_width()` now handles `difftime`/`hms` objects (@bhogan-mitre, #244).
Expand Down
24 changes: 14 additions & 10 deletions R/label-expression.R
Original file line number Diff line number Diff line change
Expand Up @@ -21,18 +21,10 @@
#' # Use label_math() with continuous scales
#' demo_continuous(c(1, 5))
#' demo_continuous(c(1, 5), labels = label_math(alpha[.x]))
#' demo_continuous(c(1, 5), labels = label_math())
label_parse <- function() {
# From ggplot2:::parse_safe
# See https://github.com/tidyverse/ggplot2/issues/2864 for discussion.
function(text) {
text <- as.character(text)

out <- vector("expression", length(text))
for (i in seq_along(text)) {
expr <- parse(text = text[[i]])
out[[i]] <- if (length(expr) == 0) NA else expr[[1]]
}
out
parse_safe(as.character(text))
}
}

Expand Down Expand Up @@ -68,3 +60,15 @@ parse_format <- label_parse
#' @rdname label_parse
#' @export
math_format <- label_math


# From ggplot2:::parse_safe
# See https://github.com/tidyverse/ggplot2/issues/2864 for discussion.
parse_safe <- function(text) {
out <- vector("expression", length(text))
for (i in seq_along(text)) {
expr <- parse(text = text[[i]])
out[[i]] <- if (length(expr) == 0) NA else expr[[1]]
}
out
}
30 changes: 30 additions & 0 deletions R/label-log.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
#' Label numbers in log format (10^3, 10^6, etc)
#'
#' `label_log()` displays numbers as base^exponent, using superscript formatting.
#'
#' @param base Base of logarithm to use
#' @param digits Number of significant digits to show for the exponent. Argument
#' is passed on to [base::format()].
#' @inherit number_format return
#' @seealso [breaks_log()] for the related breaks algorithm.
#' @export
#' @family labels for log scales
#' @examples
#' demo_log10(c(1, 1e5), labels = label_log())
#' demo_log10(c(1, 1e5), breaks = breaks_log(base = 2), labels = label_log(base = 2))
label_log <- function(base = 10, digits = 3) {
function(x) {
if (length(x) == 0) {
return(expression())
}

exponent <- format(log(x, base = base), digits = digits)
text <- paste0(base, "^", exponent)
ret <- parse_safe(text)

# restore NAs from input vector
ret[is.na(x)] <- NA

ret
}
}
1 change: 1 addition & 0 deletions man/label_bytes.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

40 changes: 40 additions & 0 deletions man/label_log.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions man/label_number_si.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions man/label_parse.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions man/label_scientific.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 8 additions & 0 deletions tests/testthat/test-label-log.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
test_that("label_log() returns expression", {
expect_identical(label_log()(numeric()), expression())
expect_identical(label_log()(NA_real_), expression(NA))

expect_equal(label_log()(c(0.1, 10)), expression(10^-1, 10^1))
expect_equal(label_log(base = 2)(8), expression(2^3))
expect_equal(label_log(base = 2, digits = 3)(7), expression(2^2.81))
})

0 comments on commit eb3e544

Please sign in to comment.