Skip to content

Commit

Permalink
a generic number formatter
Browse files Browse the repository at this point in the history
  • Loading branch information
larmarange committed Jul 6, 2018
1 parent 024fe28 commit 610e850
Show file tree
Hide file tree
Showing 4 changed files with 35 additions and 43 deletions.
2 changes: 2 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@

* Function `colour_ramp()` now uses `alpha = TRUE` by default (@clauswilke, #108).

* New function `number_format()`, a generic formatter for numbers (@larmarange, #142).

# scales 0.5.0

* New function `regular_minor_breaks()` calculates minor breaks as a property
Expand Down
35 changes: 15 additions & 20 deletions R/formatter.r
Original file line number Diff line number Diff line change
@@ -1,20 +1,19 @@
#' Number formatter: a generic formatter for numbers
#'
#' @return `number_format` returns a function with single parameter
#' `x`, a numeric vector, that returns a character vector
#' @param x a numeric vector to format
#' @param accuracy number to round to, `NULL` for automatic guess
#' @param scale a scaling factor: `x` will be multiply by `scale` before
#' formating (useful if the underlying data is on another scale,
#' e.g. for computing percentages or thousands)
#' @param prefix,suffix symbols to display before and after value
#' @param big.mark character used between every 3 digits to separate thousands,
#' a comma by default or a space if comma is already used for `decimal.mark`
#' @param decimal.mark the character to be used to indicate the numeric
#' decimal point
#' @param trim logical, if `FALSE`, values are right-justified to a common
#' width (see [base::format()])
#' @param ... other arguments passed on to [base::format()]
#' `x`, a numeric vector, that returns a character vector.
#' @param x A numeric vector to format.
#' @param accuracy Number to round to, `NULL` for automatic guess.
#' @param scale A scaling factor: `x` will be multiply by `scale` before
#' formating (useful if the underlying data is on another scale,
#' e.g. for computing percentages or thousands).
#' @param prefix,suffix Symbols to display before and after value.
#' @param big.mark Character used between every 3 digits to separate thousands.
#' @param decimal.mark The character to be used to indicate the numeric
#' decimal point.
#' @param trim Logical, if `FALSE`, values are right-justified to a common
#' width (see [base::format()]).
#' @param ... Other arguments passed on to [base::format()].
#' @export
#' @examples
#' v <- c(12.3, 4, 12345.789, 0.0002)
Expand All @@ -35,7 +34,7 @@
#' )
#' per_mille(v)
number_format <- function(accuracy = 1, scale = 1, prefix = "",
suffix = "", big.mark = NULL, decimal.mark = ".",
suffix = "", big.mark = " " , decimal.mark = ".",
trim = TRUE, ...) {
function(x) number(
x,
Expand All @@ -53,18 +52,14 @@ number_format <- function(accuracy = 1, scale = 1, prefix = "",
#' @export
#' @rdname number_format
number <- function(x, accuracy = 1, scale = 1, prefix = "",
suffix = "", big.mark = NULL, decimal.mark = ".",
suffix = "", big.mark = " ", decimal.mark = ".",
trim = TRUE, ...) {
if (length(x) == 0) return(character())
accuracy <- accuracy %||% precision(x)
x <- round_any(x, accuracy / scale)
nsmall <- -floor(log10(accuracy))
nsmall <- min(max(nsmall, 0), 20)

if (is.null(big.mark)) {
big.mark = if (identical(decimal.mark, ",")) " " else ","
}

ret <- format(
scale * x,
big.mark = big.mark,
Expand Down
29 changes: 14 additions & 15 deletions man/number_format.Rd

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

12 changes: 4 additions & 8 deletions tests/testthat/test-formatter.r
Original file line number Diff line number Diff line change
Expand Up @@ -14,20 +14,16 @@ test_that("number format works correctly", {
expect_equal(number(123.45, accuracy = 10), "120")
expect_equal(number(123.45, accuracy = .25), "123.5")
expect_equal(
number(12345, big.mark = "'"),
"12'345"
number(12345, big.mark = ","),
"12,345"
)
expect_equal(
number(12.3, decimal.mark = ",", accuracy = .1),
"12,3"
)
expect_equal(
number(12345.6, decimal.mark = ",", accuracy = .1),
"12 345,6"
)
expect_equal(
number(1.234, scale = 1000),
"1,234"
number(1.234, scale = 100),
"123"
)
expect_equal(
number(123, prefix = "pre", suffix = "post"),
Expand Down

0 comments on commit 610e850

Please sign in to comment.