Skip to content

Commit

Permalink
Add pretty_* suite of functions (#69)
Browse files Browse the repository at this point in the history
* fix typo in contributing guide

* start to add get_clean_sql and tests (WIP)

* add code cov details to contributing file

* Add link to reference documentation in the examples section

* commit current progress adding unit tests (WIP)

* fix typo in contributing guide

* start to add get_clean_sql and tests (WIP)

* add code cov details to contributing file

* Add link to reference documentation in the examples section

* commit current progress adding unit tests (WIP)

* fix tests for sql function

* add roxygen2 examples to contributing file

* add connecting to sql vignette

* update get clean sql, contributing and reference documentation

* Increment version number to 0.2.0

* tidy package following lintr advice

* remove capitalised extension test (causes test errors on linux)

* add Jen as a contributor to the package

* Initial response to PR comments (more to complete on troubleshooting)

* fix lint issues

* update connecting to sql vignette to specific select style queries only

* update wordlist and rebuild package docs

* add pretty_filesize()

* add comma_sep()

* tidy up refernce page

* add family and seealso links

* add pretty_time_taken()

* add roxygen2 shortcuts to contributing file

* add pretty_num()

* Update examples in readme

* Increment version number to 0.3.0
  • Loading branch information
cjrace authored Apr 5, 2024
1 parent abd6e19 commit 6f5aca1
Show file tree
Hide file tree
Showing 26 changed files with 818 additions and 17 deletions.
8 changes: 6 additions & 2 deletions .github/CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,14 +49,16 @@ Where possible, we'd recommend following the [Test Driven Development (TDD)](htt
``` r
usethis::use_test("name_of_new_function")
```
Feel free to have a look in the /tests/test_that folder for some examples if you want to see example tests in practice.


2. Write just enough code so that the tests pass. Again, either edit an existing function, or add a new R script using:

``` r
usethis::use_r("name_of_new_function")
```

3. Add documentation for what you've done. Follow the [roxygen2](https://roxygen2.r-lib.org/articles/rd.html) pattern for comments. Here's an example of what it looks like for a basic `add()` function:
3. Add documentation for what you've done. Follow the [roxygen2](https://roxygen2.r-lib.org/articles/rd.html) pattern for comments. You can add a standard skeleton using `Code > Insert Roxygen Skeleton` or by `Ctrl+Shift+Alt+R` when in your R script. Here's an example of what it looks like for a basic `add()` function:

```
#' @description Add together two numbers
Expand All @@ -72,7 +74,9 @@ add <- function(x, y) {
}
```

4. Continue to improve code while keeping tests passing. You can automatically style code using:
4. Continue to improve code while keeping tests passing.

5. Automatically style code using:

``` r
styler::style_pkg()
Expand Down
2 changes: 1 addition & 1 deletion DESCRIPTION
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
Type: Package
Package: dfeR
Title: Common DfE R tasks
Version: 0.2.0
Version: 0.3.0
Authors@R: c(
person("Cam", "Race", , "[email protected]", role = c("aut", "cre")),
person("Laura", "Selby", , "[email protected]", role = "aut"),
Expand Down
4 changes: 4 additions & 0 deletions NAMESPACE
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
# Generated by roxygen2: do not edit by hand

export(comma_sep)
export(format_ay)
export(format_ay_reverse)
export(format_fy)
export(format_fy_reverse)
export(get_clean_sql)
export(pretty_filesize)
export(pretty_num)
export(pretty_time_taken)
export(round_five_up)
importFrom(lifecycle,deprecated)
16 changes: 14 additions & 2 deletions NEWS.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,15 @@
# dfeR 0.3.0

Add pretty_* functions for presenting pretty numbers:

- pretty_num()
- pretty_filesize()
- pretty_time_taken()

Add helper function for comma separating numbers:

- comma_sep()

# dfeR 0.2.0

Add function for formatting financial years:
Expand All @@ -21,5 +33,5 @@ Add default value to decimal place argument of round_five_up() function.

Relaunch of the package with two functions:

- format_ay()
- round_five_up()
- format_ay()
- round_five_up()
21 changes: 21 additions & 0 deletions R/comma_sep.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
#' Comma separate
#'
#' @description
#' Adds separating commas to big numbers.
#'
#' @param number number to be comma separated
#'
#' @return string containing comma separated number
#' @export
#'
#' @examples
#' comma_sep(100)
#' comma_sep(1000)
#' comma_sep(3567000)
comma_sep <- function(number) {
if (!is.numeric(number)) {
stop("number must be a numeric value")
}

format(number, big.mark = ",", trim = TRUE, scientific = FALSE)
}
2 changes: 2 additions & 0 deletions R/format_ay.R
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#'
#' @param year Academic year
#' @return Character vector of formatted academic year
#' @family formatting functions
#' @export
#' @examples
#' format_ay(201617)
Expand All @@ -26,6 +27,7 @@ format_ay <- function(year) {
#'
#' @param year Academic year
#' @return Unformatted 6 digit year as string
#' @family formatting functions
#' @export
#' @examples
#' format_ay_reverse("2016/17")
Expand Down
2 changes: 2 additions & 0 deletions R/format_fy.R
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#'
#' @param year Financial year
#' @return Character vector of formatted financial year
#' @family formatting functions
#' @export
#' @examples
#' format_fy(201617)
Expand All @@ -26,6 +27,7 @@ format_fy <- function(year) {
#'
#' @param year Financial year
#' @return Unformatted 6 digit year as string
#' @family formatting functions
#' @export
#' @examples
#' format_fy_reverse("2016-17")
Expand Down
55 changes: 55 additions & 0 deletions R/pretty_filesize.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
#' Pretty numbers into readable file size
#'
#' @description
#' Converts a raw file size from bytes to a more readable format.
#'
#' @details
#' Designed to be used in conjunction with the file.size()
#' function in base R.
#'
#' Presents in kilobytes, megabytes or gigabytes.
#'
#' Shows as bytes until 1 KB, then kilobytes up to 1 MB, then megabytes
#' until 1GB, then it will show as gigabytes for anything larger.
#'
#' Rounds the end result to 2 decimal places.
#'
#' Using base 10 (decimal), so 1024 bytes is 1,024 KB.
#'
#' @param filesize file size in bytes
#'
#' @return string containing prettified file size
#' @family prettying functions
#' @seealso [comma_sep()] [round_five_up()]
#' @export
#' @examples
#' pretty_filesize(2)
#' pretty_filesize(549302)
#' pretty_filesize(9872948939)
#' pretty_filesize(1)
#' pretty_filesize(1000)
#' pretty_filesize(1000^2)
#' pretty_filesize(10^9)
pretty_filesize <- function(filesize) {
if (!is.numeric(filesize)) {
stop("file size must be a numeric value")
} else {
if (round_five_up(filesize / 10^9, 2) >= 1) {
return(paste0(comma_sep(round_five_up(filesize / 10^9, 2)), " GB"))
} else {
if (round_five_up(filesize / 1000^2, 2) >= 1) {
return(paste0(round_five_up(filesize / 1000^2, 2), " MB"))
} else {
if (round_five_up(filesize, 2) >= 1000) {
return(paste0(round_five_up(filesize / 1000, 2), " KB"))
} else {
if (filesize == 1) {
"1 byte"
} else {
return(paste0(round_five_up(filesize, 2), " bytes"))
}
}
}
}
}
}
128 changes: 128 additions & 0 deletions R/pretty_num.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
#' Prettify big numbers into a readable format
#'
#' @description
#' Uses `as.numeric()` to force a numeric value and then formats prettily
#' for easy presentation in console messages, reports, or dashboards.
#'
#' This rounds to 2 decimal places by default, and adds in comma separators.
#'
#' Expect that this will commonly be used for adding the pound symbol,
#' the percentage symbol, or to have a +/- prefixed based on the value.
#'
#' If applying over multiple or unpredictable values and you want to preserve
#' a non-numeric symbol such as "x" or "c" for data not available, use the
#' `ignore_na = TRUE` argument to return those values unaffected.
#'
#' If you want to customise what NA values are returned as, use the `alt_na`
#' argument.
#'
#' This function silences the warning around NAs being introduced by coercion.
#' @param value value to be prettified
#' @param prefix prefix for the value, if "+/-" then it will automatically
#' assign + or - based on the value
#' @param gbp whether to add the pound symbol or not, defaults to not
#' @param suffix suffix for the value, e.g. "%"
#' @param dp number of decimal places to round to, 2 by default
#' @param ignore_na whether to skip function for strings that can't be
#' converted and return original value
#' @param alt_na alternative value to return in place of NA, e.g. "x"
#'
#' @return string featuring prettified value
#' @family prettying functions
#' @seealso [comma_sep()] [round_five_up()] [as.numeric()]
#' @export
#'
#' @examples
#' # On individual values
#' pretty_num(5789, gbp = TRUE)
#' pretty_num(564, prefix = "+/-")
#' pretty_num(567812343223, gbp = TRUE, prefix = "+/-")
#' pretty_num(11^9, gbp = TRUE, dp = 3)
#' pretty_num(-11^8, gbp = TRUE, dp = -1)
#' pretty_num("56.089", suffix = "%")
#' pretty_num("x")
#' pretty_num("x", ignore_na = TRUE)
#' pretty_num("nope", alt_na = "x")
#'
#' # Applied over an example vector
#' vector <- c(3998098008, -123421421, "c", "x")
#' unlist(lapply(vector, pretty_num))
#' unlist(lapply(vector, pretty_num, prefix = "+/-", gbp = TRUE))
#'
#' # Return original values if NA
#' unlist(lapply(vector, pretty_num, ignore_na = TRUE))
#'
#' # Return alternative value in place of NA
#' unlist(lapply(vector, pretty_num, alt_na = "z"))
pretty_num <- function(
value,
prefix = "",
gbp = FALSE,
suffix = "",
dp = 2,
ignore_na = FALSE,
alt_na = FALSE) {
# Check we're only trying to prettify a single value
if (length(value) > 1) {
stop("value must be a single value, multiple values were detected")
}

# Force to numeric
num_value <- suppressWarnings(as.numeric(value))

# Check if should skip function
if (is.na(num_value)) {
if (ignore_na == TRUE) {
return(value) # return original value
} else if (alt_na != FALSE) {
return(alt_na) # return custom NA value
} else {
return(num_value) # return NA
}
}

# Convert GBP to pound symbol
if (gbp == TRUE) {
currency <- "\U00a3"
} else {
currency <- ""
}

# Add + / - symbols depending on size of value
if (prefix == "+/-") {
if (value >= 0) {
prefix <- "+"
} else {
prefix <- "-"
}
# Add in negative symbol if appropriate and not auto added with +/-
} else if (value < 0) {
prefix <- paste0("-", prefix)
}

# Add suffix and prefix, plus convert to million or billion
if (abs(num_value) >= 1.e9) {
paste0(
prefix,
currency,
comma_sep(round_five_up(abs(num_value) / 1.e9, dp = dp)),
" billion",
suffix
)
} else if (abs(num_value) >= 1.e6) {
paste0(
prefix,
currency,
comma_sep(round_five_up(abs(num_value) / 1.e6, dp = dp)),
" million",
suffix
)
} else {
paste0(
prefix,
currency,
comma_sep(round_five_up(abs(num_value), dp = dp)),
suffix
)
}
}
Loading

0 comments on commit 6f5aca1

Please sign in to comment.