From 693b4532c600c991ac058161e2fe77054fc91d1b Mon Sep 17 00:00:00 2001 From: Richard Iannone Date: Wed, 5 May 2021 11:57:54 -0400 Subject: [PATCH 01/24] Incorporate page numbering in `rtf_file()` --- R/utils_render_rtf.R | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/R/utils_render_rtf.R b/R/utils_render_rtf.R index beba8be96..0fb19dee1 100644 --- a/R/utils_render_rtf.R +++ b/R/utils_render_rtf.R @@ -181,7 +181,10 @@ rtf_header <- function(..., .charset = "ansi", .ansi_code_page = 1252) { rtf_header } -rtf_file <- function(header = NULL, document = NULL) { +rtf_file <- function(header = NULL, + document = NULL, + page_numbering.active, + page_numbering.location) { if (is.null(header) && is.null(document)) { header <- document <- "" @@ -228,6 +231,23 @@ rtf_file <- function(header = NULL, document = NULL) { header <- rtf_header(fonttbl, colortbl) } + # Include RTF code to express page numbering if `page_numbering.active = TRUE` + if (page_numbering.active) { + + document <- + paste( + document, + "\n\n", + rtf_raw( + "{", + if (page_numbering.location == "footer") "\\footer" else "\\header", + "\\qr{\n", + "Page {\\field{\\*\\fldinst {PAGE}}{\\fldrslt {Refresh >F9<}}} ", + "of {\\field{\\*\\fldinst {SECTIONPAGES}}{\\fldrslt {Refresh >F9<}}}\n", + "}\\par}" + ) + ) + } rtf_file <- list(header = header, document = document) From 696bd047abae912a6edb675ec2ab99b4c78f8e7a Mon Sep 17 00:00:00 2001 From: Richard Iannone Date: Wed, 5 May 2021 11:58:34 -0400 Subject: [PATCH 02/24] Enhance `as_rtf()` and `gt_save_rtf()` --- R/export.R | 38 +++++++++++++++++++++++++++++++++----- 1 file changed, 33 insertions(+), 5 deletions(-) diff --git a/R/export.R b/R/export.R index d50e4a63f..a36cf6e45 100644 --- a/R/export.R +++ b/R/export.R @@ -13,6 +13,12 @@ #' please refer to the **htmltools** documentation for more details on the use #' of these arguments. #' +#' If the output filename is expressed with the `.rtf` extension then an RTF +#' file will be generated. In this case, there two options that can be passed +#' through `...`: `page_numbering.active` and `page_numbering.location`. Both of +#' these options control RTF document page numbering and, by default, page +#' numbering is not activated (i.e., `page_numbering.active = FALSE`). +#' #' We can create an image file based on the HTML version of the `gt` table. With #' the filename extension `.png`, we get a PNG image file. A PDF document can be #' generated by using the `.pdf` extension. This process is facilitated by the @@ -231,12 +237,19 @@ gt_save_latex <- function(data, gt_save_rtf <- function(data, filename, path = NULL, - ...) { + ..., + page_numbering.active = FALSE, + page_numbering.location = c("header", "footer")) { + + page_numbering.location <- match.arg(page_numbering.location) filename <- gtsave_filename(path = path, filename = filename) data %>% - as_rtf() %>% + as_rtf( + page_numbering.active = page_numbering.active, + page_numbering.location = page_numbering.location + ) %>% writeLines(con = filename) } @@ -438,7 +451,15 @@ as_latex <- function(data) { #' vector. This object can be used with `writeLines()` to generate a valid .rtf #' file that can be opened by RTF readers. #' -#' @param data a table object that is created using the `gt()` function. +#' @param data A table object that is created using the `gt()` function. +#' @param page_numbering.active An option to include page numbering in the RTF +#' document. The location for page numbering text is either in the document +#' header or footer (governed by the `page_numbering.location` option). By +#' default, page numbering is not active (`FALSE`). +#' @param page_numbering.location If `page_numbering.active` is `TRUE` then this +#' option determines where the page numbering text will be placed. It will +#' either be in the RTF document `"header"` (default option) or the +#' `"footer"`. #' #' @examples #' # Use `gtcars` to create a gt table; @@ -460,7 +481,11 @@ as_latex <- function(data) { #' 13-4 #' #' @export -as_rtf <- function(data) { +as_rtf <- function(data, + page_numbering.active = FALSE, + page_numbering.location = c("header", "footer")) { + + page_numbering.location <- match.arg(page_numbering.location) # Perform input object validation stop_if_not_gt(data = data) @@ -498,7 +523,10 @@ as_rtf <- function(data) { source_notes_component ) ) - }) %>% + }, + page_numbering.active = page_numbering.active, + page_numbering.location = page_numbering.location + ) %>% as_rtf_string() if (isTRUE(getOption('knitr.in.progress'))) { From 3ed9b9c48f521460ef8dd3938c17f92db9d30d64 Mon Sep 17 00:00:00 2001 From: Richard Iannone Date: Wed, 5 May 2021 11:58:44 -0400 Subject: [PATCH 03/24] Update help files using roxygen --- man/as_rtf.Rd | 18 ++++++++++++++++-- man/gtsave.Rd | 6 ++++++ 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/man/as_rtf.Rd b/man/as_rtf.Rd index f5c4c60fb..db1db75c5 100644 --- a/man/as_rtf.Rd +++ b/man/as_rtf.Rd @@ -4,10 +4,24 @@ \alias{as_rtf} \title{Output a \strong{gt} object as RTF} \usage{ -as_rtf(data) +as_rtf( + data, + page_numbering.active = FALSE, + page_numbering.location = c("header", "footer") +) } \arguments{ -\item{data}{a table object that is created using the \code{gt()} function.} +\item{data}{A table object that is created using the \code{gt()} function.} + +\item{page_numbering.active}{An option to include page numbering in the RTF +document. The location for page numbering text is either in the document +header or footer (governed by the \code{page_numbering.location} option). By +default, page numbering is not active (\code{FALSE}).} + +\item{page_numbering.location}{If \code{page_numbering.active} is \code{TRUE} then this +option determines where the page numbering text will be placed. It will +either be in the RTF document \code{"header"} (default option) or the +\code{"footer"}.} } \description{ Get the RTF content from a \code{gt_tbl} object as as a single-element character diff --git a/man/gtsave.Rd b/man/gtsave.Rd index a371d748b..cb1a81b63 100644 --- a/man/gtsave.Rd +++ b/man/gtsave.Rd @@ -35,6 +35,12 @@ through the \code{...}. Those arguments are either \code{background} or \code{li please refer to the \strong{htmltools} documentation for more details on the use of these arguments. +If the output filename is expressed with the \code{.rtf} extension then an RTF +file will be generated. In this case, there two options that can be passed +through \code{...}: \code{page_numbering.active} and \code{page_numbering.location}. Both of +these options control RTF document page numbering and, by default, page +numbering is not activated (i.e., \code{page_numbering.active = FALSE}). + We can create an image file based on the HTML version of the \code{gt} table. With the filename extension \code{.png}, we get a PNG image file. A PDF document can be generated by using the \code{.pdf} extension. This process is facilitated by the From 560bcadf80a586d7d04d001c3a830c09e26f581d Mon Sep 17 00:00:00 2001 From: Richard Iannone Date: Wed, 5 May 2021 12:06:01 -0400 Subject: [PATCH 04/24] Swap location options, putting 'footer' first --- R/export.R | 10 +++++----- man/as_rtf.Rd | 8 ++++---- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/R/export.R b/R/export.R index a36cf6e45..f66b4cda1 100644 --- a/R/export.R +++ b/R/export.R @@ -239,7 +239,7 @@ gt_save_rtf <- function(data, path = NULL, ..., page_numbering.active = FALSE, - page_numbering.location = c("header", "footer")) { + page_numbering.location = c("footer", "header")) { page_numbering.location <- match.arg(page_numbering.location) @@ -454,12 +454,12 @@ as_latex <- function(data) { #' @param data A table object that is created using the `gt()` function. #' @param page_numbering.active An option to include page numbering in the RTF #' document. The location for page numbering text is either in the document -#' header or footer (governed by the `page_numbering.location` option). By +#' footer or header (governed by the `page_numbering.location` option). By #' default, page numbering is not active (`FALSE`). #' @param page_numbering.location If `page_numbering.active` is `TRUE` then this #' option determines where the page numbering text will be placed. It will -#' either be in the RTF document `"header"` (default option) or the -#' `"footer"`. +#' either be in the RTF document `"footer"` (default option) or the +#' `"header"`. #' #' @examples #' # Use `gtcars` to create a gt table; @@ -483,7 +483,7 @@ as_latex <- function(data) { #' @export as_rtf <- function(data, page_numbering.active = FALSE, - page_numbering.location = c("header", "footer")) { + page_numbering.location = c("footer", "header")) { page_numbering.location <- match.arg(page_numbering.location) diff --git a/man/as_rtf.Rd b/man/as_rtf.Rd index db1db75c5..5adead464 100644 --- a/man/as_rtf.Rd +++ b/man/as_rtf.Rd @@ -7,7 +7,7 @@ as_rtf( data, page_numbering.active = FALSE, - page_numbering.location = c("header", "footer") + page_numbering.location = c("footer", "header") ) } \arguments{ @@ -15,13 +15,13 @@ as_rtf( \item{page_numbering.active}{An option to include page numbering in the RTF document. The location for page numbering text is either in the document -header or footer (governed by the \code{page_numbering.location} option). By +footer or header (governed by the \code{page_numbering.location} option). By default, page numbering is not active (\code{FALSE}).} \item{page_numbering.location}{If \code{page_numbering.active} is \code{TRUE} then this option determines where the page numbering text will be placed. It will -either be in the RTF document \code{"header"} (default option) or the -\code{"footer"}.} +either be in the RTF document \code{"footer"} (default option) or the +\code{"header"}.} } \description{ Get the RTF content from a \code{gt_tbl} object as as a single-element character From b32a3801f6c61abb8f55a63bfebe2fa9f167c58e Mon Sep 17 00:00:00 2001 From: Richard Iannone Date: Wed, 5 May 2021 12:35:42 -0400 Subject: [PATCH 05/24] Add testthat snapshot tests for RTF page numbering --- tests/testthat/_snaps/rtf_page_numbering.md | 275 ++++++++++++++++++++ tests/testthat/test-rtf_page_numbering.R | 25 ++ 2 files changed, 300 insertions(+) create mode 100644 tests/testthat/_snaps/rtf_page_numbering.md create mode 100644 tests/testthat/test-rtf_page_numbering.R diff --git a/tests/testthat/_snaps/rtf_page_numbering.md b/tests/testthat/_snaps/rtf_page_numbering.md new file mode 100644 index 000000000..12fa4080d --- /dev/null +++ b/tests/testthat/_snaps/rtf_page_numbering.md @@ -0,0 +1,275 @@ +# page numbering directives can be added to RTF documents + + Code + . + Output + {\rtf\ansi\ansicpg1252{\fonttbl{\f0\froman\fcharset0\fprq0 Calibri;}{\f1\froman\fcharset0\fprq0 Courier;}}{\colortbl;\red211\green211\blue211;} + + \trowd\trrh0\trhdr + + \pard\plain\uc0\qr\clvertalc\clpadb50\clpadfb3\clpadr50\clpadfr3\clpadl50\clpadfl3\clpadt50\clpadft3\clbrdrt\brdrs\brdrw40\brdrcf1\clbrdrb\brdrs\brdrw40\brdrcf1\clbrdrl\brdrs\brdrw20\brdrcf1\clbrdrr\brdrs\brdrw20\brdrcf1\cellx1052 + \intbl {\f0 {\f0\fs20 num}}\cell + \pard\plain + + \pard\plain\uc0\ql\clvertalc\clpadb50\clpadfb3\clpadr50\clpadfr3\clpadl50\clpadfl3\clpadt50\clpadft3\clbrdrt\brdrs\brdrw40\brdrcf1\clbrdrb\brdrs\brdrw40\brdrcf1\clbrdrl\brdrs\brdrw20\brdrcf1\clbrdrr\brdrs\brdrw20\brdrcf1\cellx2104 + \intbl {\f0 {\f0\fs20 char}}\cell + \pard\plain + + \pard\plain\uc0\qc\clvertalc\clpadb50\clpadfb3\clpadr50\clpadfr3\clpadl50\clpadfl3\clpadt50\clpadft3\clbrdrt\brdrs\brdrw40\brdrcf1\clbrdrb\brdrs\brdrw40\brdrcf1\clbrdrl\brdrs\brdrw20\brdrcf1\clbrdrr\brdrs\brdrw20\brdrcf1\cellx3156 + \intbl {\f0 {\f0\fs20 fctr}}\cell + \pard\plain + + \pard\plain\uc0\ql\clvertalc\clpadb50\clpadfb3\clpadr50\clpadfr3\clpadl50\clpadfl3\clpadt50\clpadft3\clbrdrt\brdrs\brdrw40\brdrcf1\clbrdrb\brdrs\brdrw40\brdrcf1\clbrdrl\brdrs\brdrw20\brdrcf1\clbrdrr\brdrs\brdrw20\brdrcf1\cellx4208 + \intbl {\f0 {\f0\fs20 date}}\cell + \pard\plain + + \pard\plain\uc0\ql\clvertalc\clpadb50\clpadfb3\clpadr50\clpadfr3\clpadl50\clpadfl3\clpadt50\clpadft3\clbrdrt\brdrs\brdrw40\brdrcf1\clbrdrb\brdrs\brdrw40\brdrcf1\clbrdrl\brdrs\brdrw20\brdrcf1\clbrdrr\brdrs\brdrw20\brdrcf1\cellx5260 + \intbl {\f0 {\f0\fs20 time}}\cell + \pard\plain + + \pard\plain\uc0\ql\clvertalc\clpadb50\clpadfb3\clpadr50\clpadfr3\clpadl50\clpadfl3\clpadt50\clpadft3\clbrdrt\brdrs\brdrw40\brdrcf1\clbrdrb\brdrs\brdrw40\brdrcf1\clbrdrl\brdrs\brdrw20\brdrcf1\clbrdrr\brdrs\brdrw20\brdrcf1\cellx6312 + \intbl {\f0 {\f0\fs20 datetime}}\cell + \pard\plain + + \pard\plain\uc0\qr\clvertalc\clpadb50\clpadfb3\clpadr50\clpadfr3\clpadl50\clpadfl3\clpadt50\clpadft3\clbrdrt\brdrs\brdrw40\brdrcf1\clbrdrb\brdrs\brdrw40\brdrcf1\clbrdrl\brdrs\brdrw20\brdrcf1\clbrdrr\brdrs\brdrw20\brdrcf1\cellx7364 + \intbl {\f0 {\f0\fs20 currency}}\cell + \pard\plain + + \pard\plain\uc0\ql\clvertalc\clpadb50\clpadfb3\clpadr50\clpadfr3\clpadl50\clpadfl3\clpadt50\clpadft3\clbrdrt\brdrs\brdrw40\brdrcf1\clbrdrb\brdrs\brdrw40\brdrcf1\clbrdrl\brdrs\brdrw20\brdrcf1\clbrdrr\brdrs\brdrw20\brdrcf1\cellx8416 + \intbl {\f0 {\f0\fs20 row}}\cell + \pard\plain + + \pard\plain\uc0\ql\clvertalc\clpadb50\clpadfb3\clpadr50\clpadfr3\clpadl50\clpadfl3\clpadt50\clpadft3\clbrdrt\brdrs\brdrw40\brdrcf1\clbrdrb\brdrs\brdrw40\brdrcf1\clbrdrl\brdrs\brdrw20\brdrcf1\clbrdrr\brdrs\brdrw20\brdrcf1\cellx9468 + \intbl {\f0 {\f0\fs20 group}}\cell + \pard\plain + + \row + + \trowd\trrh0 + + \pard\plain\uc0\qr\clvertalc\clpadb50\clpadfb3\clpadr50\clpadfr3\clpadl50\clpadfl3\clpadt50\clpadft3\clbrdrb\brdrs\brdrw10\brdrcf1\clbrdrl\brdrs\brdrw10\brdrcf1\clbrdrr\brdrs\brdrw10\brdrcf1\cellx1052 + \intbl {\f0 {\f0\fs20 0.1111}}\cell + \pard\plain + + \pard\plain\uc0\ql\clvertalc\clpadb50\clpadfb3\clpadr50\clpadfr3\clpadl50\clpadfl3\clpadt50\clpadft3\clbrdrb\brdrs\brdrw10\brdrcf1\clbrdrl\brdrs\brdrw10\brdrcf1\clbrdrr\brdrs\brdrw10\brdrcf1\cellx2104 + \intbl {\f0 {\f0\fs20 apricot}}\cell + \pard\plain + + \pard\plain\uc0\qc\clvertalc\clpadb50\clpadfb3\clpadr50\clpadfr3\clpadl50\clpadfl3\clpadt50\clpadft3\clbrdrb\brdrs\brdrw10\brdrcf1\clbrdrl\brdrs\brdrw10\brdrcf1\clbrdrr\brdrs\brdrw10\brdrcf1\cellx3156 + \intbl {\f0 {\f0\fs20 one}}\cell + \pard\plain + + \pard\plain\uc0\ql\clvertalc\clpadb50\clpadfb3\clpadr50\clpadfr3\clpadl50\clpadfl3\clpadt50\clpadft3\clbrdrb\brdrs\brdrw10\brdrcf1\clbrdrl\brdrs\brdrw10\brdrcf1\clbrdrr\brdrs\brdrw10\brdrcf1\cellx4208 + \intbl {\f0 {\f0\fs20 2015-01-15}}\cell + \pard\plain + + \pard\plain\uc0\ql\clvertalc\clpadb50\clpadfb3\clpadr50\clpadfr3\clpadl50\clpadfl3\clpadt50\clpadft3\clbrdrb\brdrs\brdrw10\brdrcf1\clbrdrl\brdrs\brdrw10\brdrcf1\clbrdrr\brdrs\brdrw10\brdrcf1\cellx5260 + \intbl {\f0 {\f0\fs20 13:35}}\cell + \pard\plain + + \pard\plain\uc0\ql\clvertalc\clpadb50\clpadfb3\clpadr50\clpadfr3\clpadl50\clpadfl3\clpadt50\clpadft3\clbrdrb\brdrs\brdrw10\brdrcf1\clbrdrl\brdrs\brdrw10\brdrcf1\clbrdrr\brdrs\brdrw10\brdrcf1\cellx6312 + \intbl {\f0 {\f0\fs20 2018-01-01 02:22}}\cell + \pard\plain + + \pard\plain\uc0\qr\clvertalc\clpadb50\clpadfb3\clpadr50\clpadfr3\clpadl50\clpadfl3\clpadt50\clpadft3\clbrdrb\brdrs\brdrw10\brdrcf1\clbrdrl\brdrs\brdrw10\brdrcf1\clbrdrr\brdrs\brdrw10\brdrcf1\cellx7364 + \intbl {\f0 {\f0\fs20 49.95}}\cell + \pard\plain + + \pard\plain\uc0\ql\clvertalc\clpadb50\clpadfb3\clpadr50\clpadfr3\clpadl50\clpadfl3\clpadt50\clpadft3\clbrdrb\brdrs\brdrw10\brdrcf1\clbrdrl\brdrs\brdrw10\brdrcf1\clbrdrr\brdrs\brdrw10\brdrcf1\cellx8416 + \intbl {\f0 {\f0\fs20 row_1}}\cell + \pard\plain + + \pard\plain\uc0\ql\clvertalc\clpadb50\clpadfb3\clpadr50\clpadfr3\clpadl50\clpadfl3\clpadt50\clpadft3\clbrdrb\brdrs\brdrw10\brdrcf1\clbrdrl\brdrs\brdrw10\brdrcf1\clbrdrr\brdrs\brdrw10\brdrcf1\cellx9468 + \intbl {\f0 {\f0\fs20 grp_a}}\cell + \pard\plain + + \row + + } + +--- + + Code + . + Output + {\rtf\ansi\ansicpg1252{\fonttbl{\f0\froman\fcharset0\fprq0 Calibri;}{\f1\froman\fcharset0\fprq0 Courier;}}{\colortbl;\red211\green211\blue211;} + + \trowd\trrh0\trhdr + + \pard\plain\uc0\qr\clvertalc\clpadb50\clpadfb3\clpadr50\clpadfr3\clpadl50\clpadfl3\clpadt50\clpadft3\clbrdrt\brdrs\brdrw40\brdrcf1\clbrdrb\brdrs\brdrw40\brdrcf1\clbrdrl\brdrs\brdrw20\brdrcf1\clbrdrr\brdrs\brdrw20\brdrcf1\cellx1052 + \intbl {\f0 {\f0\fs20 num}}\cell + \pard\plain + + \pard\plain\uc0\ql\clvertalc\clpadb50\clpadfb3\clpadr50\clpadfr3\clpadl50\clpadfl3\clpadt50\clpadft3\clbrdrt\brdrs\brdrw40\brdrcf1\clbrdrb\brdrs\brdrw40\brdrcf1\clbrdrl\brdrs\brdrw20\brdrcf1\clbrdrr\brdrs\brdrw20\brdrcf1\cellx2104 + \intbl {\f0 {\f0\fs20 char}}\cell + \pard\plain + + \pard\plain\uc0\qc\clvertalc\clpadb50\clpadfb3\clpadr50\clpadfr3\clpadl50\clpadfl3\clpadt50\clpadft3\clbrdrt\brdrs\brdrw40\brdrcf1\clbrdrb\brdrs\brdrw40\brdrcf1\clbrdrl\brdrs\brdrw20\brdrcf1\clbrdrr\brdrs\brdrw20\brdrcf1\cellx3156 + \intbl {\f0 {\f0\fs20 fctr}}\cell + \pard\plain + + \pard\plain\uc0\ql\clvertalc\clpadb50\clpadfb3\clpadr50\clpadfr3\clpadl50\clpadfl3\clpadt50\clpadft3\clbrdrt\brdrs\brdrw40\brdrcf1\clbrdrb\brdrs\brdrw40\brdrcf1\clbrdrl\brdrs\brdrw20\brdrcf1\clbrdrr\brdrs\brdrw20\brdrcf1\cellx4208 + \intbl {\f0 {\f0\fs20 date}}\cell + \pard\plain + + \pard\plain\uc0\ql\clvertalc\clpadb50\clpadfb3\clpadr50\clpadfr3\clpadl50\clpadfl3\clpadt50\clpadft3\clbrdrt\brdrs\brdrw40\brdrcf1\clbrdrb\brdrs\brdrw40\brdrcf1\clbrdrl\brdrs\brdrw20\brdrcf1\clbrdrr\brdrs\brdrw20\brdrcf1\cellx5260 + \intbl {\f0 {\f0\fs20 time}}\cell + \pard\plain + + \pard\plain\uc0\ql\clvertalc\clpadb50\clpadfb3\clpadr50\clpadfr3\clpadl50\clpadfl3\clpadt50\clpadft3\clbrdrt\brdrs\brdrw40\brdrcf1\clbrdrb\brdrs\brdrw40\brdrcf1\clbrdrl\brdrs\brdrw20\brdrcf1\clbrdrr\brdrs\brdrw20\brdrcf1\cellx6312 + \intbl {\f0 {\f0\fs20 datetime}}\cell + \pard\plain + + \pard\plain\uc0\qr\clvertalc\clpadb50\clpadfb3\clpadr50\clpadfr3\clpadl50\clpadfl3\clpadt50\clpadft3\clbrdrt\brdrs\brdrw40\brdrcf1\clbrdrb\brdrs\brdrw40\brdrcf1\clbrdrl\brdrs\brdrw20\brdrcf1\clbrdrr\brdrs\brdrw20\brdrcf1\cellx7364 + \intbl {\f0 {\f0\fs20 currency}}\cell + \pard\plain + + \pard\plain\uc0\ql\clvertalc\clpadb50\clpadfb3\clpadr50\clpadfr3\clpadl50\clpadfl3\clpadt50\clpadft3\clbrdrt\brdrs\brdrw40\brdrcf1\clbrdrb\brdrs\brdrw40\brdrcf1\clbrdrl\brdrs\brdrw20\brdrcf1\clbrdrr\brdrs\brdrw20\brdrcf1\cellx8416 + \intbl {\f0 {\f0\fs20 row}}\cell + \pard\plain + + \pard\plain\uc0\ql\clvertalc\clpadb50\clpadfb3\clpadr50\clpadfr3\clpadl50\clpadfl3\clpadt50\clpadft3\clbrdrt\brdrs\brdrw40\brdrcf1\clbrdrb\brdrs\brdrw40\brdrcf1\clbrdrl\brdrs\brdrw20\brdrcf1\clbrdrr\brdrs\brdrw20\brdrcf1\cellx9468 + \intbl {\f0 {\f0\fs20 group}}\cell + \pard\plain + + \row + + \trowd\trrh0 + + \pard\plain\uc0\qr\clvertalc\clpadb50\clpadfb3\clpadr50\clpadfr3\clpadl50\clpadfl3\clpadt50\clpadft3\clbrdrb\brdrs\brdrw10\brdrcf1\clbrdrl\brdrs\brdrw10\brdrcf1\clbrdrr\brdrs\brdrw10\brdrcf1\cellx1052 + \intbl {\f0 {\f0\fs20 0.1111}}\cell + \pard\plain + + \pard\plain\uc0\ql\clvertalc\clpadb50\clpadfb3\clpadr50\clpadfr3\clpadl50\clpadfl3\clpadt50\clpadft3\clbrdrb\brdrs\brdrw10\brdrcf1\clbrdrl\brdrs\brdrw10\brdrcf1\clbrdrr\brdrs\brdrw10\brdrcf1\cellx2104 + \intbl {\f0 {\f0\fs20 apricot}}\cell + \pard\plain + + \pard\plain\uc0\qc\clvertalc\clpadb50\clpadfb3\clpadr50\clpadfr3\clpadl50\clpadfl3\clpadt50\clpadft3\clbrdrb\brdrs\brdrw10\brdrcf1\clbrdrl\brdrs\brdrw10\brdrcf1\clbrdrr\brdrs\brdrw10\brdrcf1\cellx3156 + \intbl {\f0 {\f0\fs20 one}}\cell + \pard\plain + + \pard\plain\uc0\ql\clvertalc\clpadb50\clpadfb3\clpadr50\clpadfr3\clpadl50\clpadfl3\clpadt50\clpadft3\clbrdrb\brdrs\brdrw10\brdrcf1\clbrdrl\brdrs\brdrw10\brdrcf1\clbrdrr\brdrs\brdrw10\brdrcf1\cellx4208 + \intbl {\f0 {\f0\fs20 2015-01-15}}\cell + \pard\plain + + \pard\plain\uc0\ql\clvertalc\clpadb50\clpadfb3\clpadr50\clpadfr3\clpadl50\clpadfl3\clpadt50\clpadft3\clbrdrb\brdrs\brdrw10\brdrcf1\clbrdrl\brdrs\brdrw10\brdrcf1\clbrdrr\brdrs\brdrw10\brdrcf1\cellx5260 + \intbl {\f0 {\f0\fs20 13:35}}\cell + \pard\plain + + \pard\plain\uc0\ql\clvertalc\clpadb50\clpadfb3\clpadr50\clpadfr3\clpadl50\clpadfl3\clpadt50\clpadft3\clbrdrb\brdrs\brdrw10\brdrcf1\clbrdrl\brdrs\brdrw10\brdrcf1\clbrdrr\brdrs\brdrw10\brdrcf1\cellx6312 + \intbl {\f0 {\f0\fs20 2018-01-01 02:22}}\cell + \pard\plain + + \pard\plain\uc0\qr\clvertalc\clpadb50\clpadfb3\clpadr50\clpadfr3\clpadl50\clpadfl3\clpadt50\clpadft3\clbrdrb\brdrs\brdrw10\brdrcf1\clbrdrl\brdrs\brdrw10\brdrcf1\clbrdrr\brdrs\brdrw10\brdrcf1\cellx7364 + \intbl {\f0 {\f0\fs20 49.95}}\cell + \pard\plain + + \pard\plain\uc0\ql\clvertalc\clpadb50\clpadfb3\clpadr50\clpadfr3\clpadl50\clpadfl3\clpadt50\clpadft3\clbrdrb\brdrs\brdrw10\brdrcf1\clbrdrl\brdrs\brdrw10\brdrcf1\clbrdrr\brdrs\brdrw10\brdrcf1\cellx8416 + \intbl {\f0 {\f0\fs20 row_1}}\cell + \pard\plain + + \pard\plain\uc0\ql\clvertalc\clpadb50\clpadfb3\clpadr50\clpadfr3\clpadl50\clpadfl3\clpadt50\clpadft3\clbrdrb\brdrs\brdrw10\brdrcf1\clbrdrl\brdrs\brdrw10\brdrcf1\clbrdrr\brdrs\brdrw10\brdrcf1\cellx9468 + \intbl {\f0 {\f0\fs20 grp_a}}\cell + \pard\plain + + \row + + + + {\footer\qr{ + Page {\field{\*\fldinst {PAGE}}{\fldrslt {Refresh >F9<}}} of {\field{\*\fldinst {SECTIONPAGES}}{\fldrslt {Refresh >F9<}}} + }\par}} + +--- + + Code + . + Output + {\rtf\ansi\ansicpg1252{\fonttbl{\f0\froman\fcharset0\fprq0 Calibri;}{\f1\froman\fcharset0\fprq0 Courier;}}{\colortbl;\red211\green211\blue211;} + + \trowd\trrh0\trhdr + + \pard\plain\uc0\qr\clvertalc\clpadb50\clpadfb3\clpadr50\clpadfr3\clpadl50\clpadfl3\clpadt50\clpadft3\clbrdrt\brdrs\brdrw40\brdrcf1\clbrdrb\brdrs\brdrw40\brdrcf1\clbrdrl\brdrs\brdrw20\brdrcf1\clbrdrr\brdrs\brdrw20\brdrcf1\cellx1052 + \intbl {\f0 {\f0\fs20 num}}\cell + \pard\plain + + \pard\plain\uc0\ql\clvertalc\clpadb50\clpadfb3\clpadr50\clpadfr3\clpadl50\clpadfl3\clpadt50\clpadft3\clbrdrt\brdrs\brdrw40\brdrcf1\clbrdrb\brdrs\brdrw40\brdrcf1\clbrdrl\brdrs\brdrw20\brdrcf1\clbrdrr\brdrs\brdrw20\brdrcf1\cellx2104 + \intbl {\f0 {\f0\fs20 char}}\cell + \pard\plain + + \pard\plain\uc0\qc\clvertalc\clpadb50\clpadfb3\clpadr50\clpadfr3\clpadl50\clpadfl3\clpadt50\clpadft3\clbrdrt\brdrs\brdrw40\brdrcf1\clbrdrb\brdrs\brdrw40\brdrcf1\clbrdrl\brdrs\brdrw20\brdrcf1\clbrdrr\brdrs\brdrw20\brdrcf1\cellx3156 + \intbl {\f0 {\f0\fs20 fctr}}\cell + \pard\plain + + \pard\plain\uc0\ql\clvertalc\clpadb50\clpadfb3\clpadr50\clpadfr3\clpadl50\clpadfl3\clpadt50\clpadft3\clbrdrt\brdrs\brdrw40\brdrcf1\clbrdrb\brdrs\brdrw40\brdrcf1\clbrdrl\brdrs\brdrw20\brdrcf1\clbrdrr\brdrs\brdrw20\brdrcf1\cellx4208 + \intbl {\f0 {\f0\fs20 date}}\cell + \pard\plain + + \pard\plain\uc0\ql\clvertalc\clpadb50\clpadfb3\clpadr50\clpadfr3\clpadl50\clpadfl3\clpadt50\clpadft3\clbrdrt\brdrs\brdrw40\brdrcf1\clbrdrb\brdrs\brdrw40\brdrcf1\clbrdrl\brdrs\brdrw20\brdrcf1\clbrdrr\brdrs\brdrw20\brdrcf1\cellx5260 + \intbl {\f0 {\f0\fs20 time}}\cell + \pard\plain + + \pard\plain\uc0\ql\clvertalc\clpadb50\clpadfb3\clpadr50\clpadfr3\clpadl50\clpadfl3\clpadt50\clpadft3\clbrdrt\brdrs\brdrw40\brdrcf1\clbrdrb\brdrs\brdrw40\brdrcf1\clbrdrl\brdrs\brdrw20\brdrcf1\clbrdrr\brdrs\brdrw20\brdrcf1\cellx6312 + \intbl {\f0 {\f0\fs20 datetime}}\cell + \pard\plain + + \pard\plain\uc0\qr\clvertalc\clpadb50\clpadfb3\clpadr50\clpadfr3\clpadl50\clpadfl3\clpadt50\clpadft3\clbrdrt\brdrs\brdrw40\brdrcf1\clbrdrb\brdrs\brdrw40\brdrcf1\clbrdrl\brdrs\brdrw20\brdrcf1\clbrdrr\brdrs\brdrw20\brdrcf1\cellx7364 + \intbl {\f0 {\f0\fs20 currency}}\cell + \pard\plain + + \pard\plain\uc0\ql\clvertalc\clpadb50\clpadfb3\clpadr50\clpadfr3\clpadl50\clpadfl3\clpadt50\clpadft3\clbrdrt\brdrs\brdrw40\brdrcf1\clbrdrb\brdrs\brdrw40\brdrcf1\clbrdrl\brdrs\brdrw20\brdrcf1\clbrdrr\brdrs\brdrw20\brdrcf1\cellx8416 + \intbl {\f0 {\f0\fs20 row}}\cell + \pard\plain + + \pard\plain\uc0\ql\clvertalc\clpadb50\clpadfb3\clpadr50\clpadfr3\clpadl50\clpadfl3\clpadt50\clpadft3\clbrdrt\brdrs\brdrw40\brdrcf1\clbrdrb\brdrs\brdrw40\brdrcf1\clbrdrl\brdrs\brdrw20\brdrcf1\clbrdrr\brdrs\brdrw20\brdrcf1\cellx9468 + \intbl {\f0 {\f0\fs20 group}}\cell + \pard\plain + + \row + + \trowd\trrh0 + + \pard\plain\uc0\qr\clvertalc\clpadb50\clpadfb3\clpadr50\clpadfr3\clpadl50\clpadfl3\clpadt50\clpadft3\clbrdrb\brdrs\brdrw10\brdrcf1\clbrdrl\brdrs\brdrw10\brdrcf1\clbrdrr\brdrs\brdrw10\brdrcf1\cellx1052 + \intbl {\f0 {\f0\fs20 0.1111}}\cell + \pard\plain + + \pard\plain\uc0\ql\clvertalc\clpadb50\clpadfb3\clpadr50\clpadfr3\clpadl50\clpadfl3\clpadt50\clpadft3\clbrdrb\brdrs\brdrw10\brdrcf1\clbrdrl\brdrs\brdrw10\brdrcf1\clbrdrr\brdrs\brdrw10\brdrcf1\cellx2104 + \intbl {\f0 {\f0\fs20 apricot}}\cell + \pard\plain + + \pard\plain\uc0\qc\clvertalc\clpadb50\clpadfb3\clpadr50\clpadfr3\clpadl50\clpadfl3\clpadt50\clpadft3\clbrdrb\brdrs\brdrw10\brdrcf1\clbrdrl\brdrs\brdrw10\brdrcf1\clbrdrr\brdrs\brdrw10\brdrcf1\cellx3156 + \intbl {\f0 {\f0\fs20 one}}\cell + \pard\plain + + \pard\plain\uc0\ql\clvertalc\clpadb50\clpadfb3\clpadr50\clpadfr3\clpadl50\clpadfl3\clpadt50\clpadft3\clbrdrb\brdrs\brdrw10\brdrcf1\clbrdrl\brdrs\brdrw10\brdrcf1\clbrdrr\brdrs\brdrw10\brdrcf1\cellx4208 + \intbl {\f0 {\f0\fs20 2015-01-15}}\cell + \pard\plain + + \pard\plain\uc0\ql\clvertalc\clpadb50\clpadfb3\clpadr50\clpadfr3\clpadl50\clpadfl3\clpadt50\clpadft3\clbrdrb\brdrs\brdrw10\brdrcf1\clbrdrl\brdrs\brdrw10\brdrcf1\clbrdrr\brdrs\brdrw10\brdrcf1\cellx5260 + \intbl {\f0 {\f0\fs20 13:35}}\cell + \pard\plain + + \pard\plain\uc0\ql\clvertalc\clpadb50\clpadfb3\clpadr50\clpadfr3\clpadl50\clpadfl3\clpadt50\clpadft3\clbrdrb\brdrs\brdrw10\brdrcf1\clbrdrl\brdrs\brdrw10\brdrcf1\clbrdrr\brdrs\brdrw10\brdrcf1\cellx6312 + \intbl {\f0 {\f0\fs20 2018-01-01 02:22}}\cell + \pard\plain + + \pard\plain\uc0\qr\clvertalc\clpadb50\clpadfb3\clpadr50\clpadfr3\clpadl50\clpadfl3\clpadt50\clpadft3\clbrdrb\brdrs\brdrw10\brdrcf1\clbrdrl\brdrs\brdrw10\brdrcf1\clbrdrr\brdrs\brdrw10\brdrcf1\cellx7364 + \intbl {\f0 {\f0\fs20 49.95}}\cell + \pard\plain + + \pard\plain\uc0\ql\clvertalc\clpadb50\clpadfb3\clpadr50\clpadfr3\clpadl50\clpadfl3\clpadt50\clpadft3\clbrdrb\brdrs\brdrw10\brdrcf1\clbrdrl\brdrs\brdrw10\brdrcf1\clbrdrr\brdrs\brdrw10\brdrcf1\cellx8416 + \intbl {\f0 {\f0\fs20 row_1}}\cell + \pard\plain + + \pard\plain\uc0\ql\clvertalc\clpadb50\clpadfb3\clpadr50\clpadfr3\clpadl50\clpadfl3\clpadt50\clpadft3\clbrdrb\brdrs\brdrw10\brdrcf1\clbrdrl\brdrs\brdrw10\brdrcf1\clbrdrr\brdrs\brdrw10\brdrcf1\cellx9468 + \intbl {\f0 {\f0\fs20 grp_a}}\cell + \pard\plain + + \row + + + + {\header\qr{ + Page {\field{\*\fldinst {PAGE}}{\fldrslt {Refresh >F9<}}} of {\field{\*\fldinst {SECTIONPAGES}}{\fldrslt {Refresh >F9<}}} + }\par}} + diff --git a/tests/testthat/test-rtf_page_numbering.R b/tests/testthat/test-rtf_page_numbering.R new file mode 100644 index 000000000..73ae0e034 --- /dev/null +++ b/tests/testthat/test-rtf_page_numbering.R @@ -0,0 +1,25 @@ +test_that("page numbering directives can be added to RTF documents", { + + local_edition(3) + + # Create a one-row table for these tests + exibble_min <- exibble[1, ] + + # Expect for there to be no directives for page numbering by default + exibble_min %>% + gt() %>% + as_rtf() %>% + expect_snapshot() + + # Expect for there to be page numbering code for the footer by default + exibble_min %>% + gt() %>% + as_rtf(page_numbering.active = TRUE) %>% + expect_snapshot() + + # Expect for there to be page numbering code for the header + exibble_min %>% + gt() %>% + as_rtf(page_numbering.active = TRUE, page_numbering.location = "header") %>% + expect_snapshot() +}) From 9ea076f1e41c1f0db7a31efae904abd9ece7524c Mon Sep 17 00:00:00 2001 From: Richard Iannone Date: Wed, 5 May 2021 13:53:49 -0400 Subject: [PATCH 06/24] Simplify page numbering text --- R/utils_render_rtf.R | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/R/utils_render_rtf.R b/R/utils_render_rtf.R index 0fb19dee1..6c9274209 100644 --- a/R/utils_render_rtf.R +++ b/R/utils_render_rtf.R @@ -241,10 +241,7 @@ rtf_file <- function(header = NULL, rtf_raw( "{", if (page_numbering.location == "footer") "\\footer" else "\\header", - "\\qr{\n", - "Page {\\field{\\*\\fldinst {PAGE}}{\\fldrslt {Refresh >F9<}}} ", - "of {\\field{\\*\\fldinst {SECTIONPAGES}}{\\fldrslt {Refresh >F9<}}}\n", - "}\\par}" + "\\qr{\n{\\field{\\*\\fldinst {PAGE}}{\\fldrslt {Refresh >F9<}}}}\\par}" ) ) } From eb75bca38ef3de04b4b239cadea0decbf6c6f80c Mon Sep 17 00:00:00 2001 From: Richard Iannone Date: Wed, 5 May 2021 13:54:08 -0400 Subject: [PATCH 07/24] Add the `fmt_bytes()` formatter function (#750) * Create first draft of `fmt_bytes()` * Simplify examples for `fmt_bytes()` * Add screenshots for `fmt_bytes()` examples * Add the `use_seps` arg to `fmt_bytes()` * Update fmt_bytes.Rd * Handle cases where values are in high YBs * Add tests for `fmt_bytes()` * Refactor `fmt_bytes()` * Use `log()` instead of `log10()` * Update test-fmt_bytes.R * Update _pkgdown.yml --- NAMESPACE | 1 + R/format_data.R | 155 +++++++++++- R/utils_formatters.R | 4 + _pkgdown.yml | 1 + man/data_color.Rd | 1 + man/figures/man_fmt_bytes_1.png | Bin 0 -> 7792 bytes man/figures/man_fmt_bytes_2.png | Bin 0 -> 8438 bytes man/fmt.Rd | 3 +- man/fmt_bytes.Rd | 157 ++++++++++++ man/fmt_currency.Rd | 1 + man/fmt_date.Rd | 3 +- man/fmt_datetime.Rd | 3 +- man/fmt_markdown.Rd | 3 +- man/fmt_missing.Rd | 3 +- man/fmt_number.Rd | 1 + man/fmt_passthrough.Rd | 3 +- man/fmt_percent.Rd | 1 + man/fmt_scientific.Rd | 5 +- man/fmt_time.Rd | 3 +- man/text_transform.Rd | 1 + tests/testthat/test-fmt_bytes.R | 433 ++++++++++++++++++++++++++++++++ 21 files changed, 765 insertions(+), 17 deletions(-) create mode 100644 man/figures/man_fmt_bytes_1.png create mode 100644 man/figures/man_fmt_bytes_2.png create mode 100644 man/fmt_bytes.Rd create mode 100644 tests/testthat/test-fmt_bytes.R diff --git a/NAMESPACE b/NAMESPACE index 17c7bfa2c..6ad0cc004 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -47,6 +47,7 @@ export(escape_latex) export(everything) export(extract_summary) export(fmt) +export(fmt_bytes) export(fmt_currency) export(fmt_date) export(fmt_datetime) diff --git a/R/format_data.R b/R/format_data.R index 86f6d48de..22d87842e 100644 --- a/R/format_data.R +++ b/R/format_data.R @@ -242,6 +242,8 @@ fmt_number <- function(data, #' argument. See the Arguments section for more information on this. #' #' @inheritParams fmt_number +#' @param scale_by A value to scale the input. The default is `1.0`. All numeric +#' values will be multiplied by this value first before undergoing formatting. #' #' @return An object of class `gt_tbl`. #' @@ -769,6 +771,145 @@ fmt_currency <- function(data, ) } +#' Format values as bytes +#' +#' With numeric values in a **gt** table, we can transform those to values of +#' bytes with human readable units. The `fmt_bytes()` function allows for the +#' formatting of byte sizes to either of two common representations: (1) with +#' decimal units (powers of 1000, examples being `"kB"` and `"MB"`), and (2) +#' with binary units (powers of 1024, examples being `"KiB"` and `"MiB"`). +#' +#' It is assumed the input numeric values represent the number of bytes and +#' automatic truncation of values will occur. The numeric values will be scaled +#' to be in the range of 1 to <1000 and then decorated with the correct unit +#' symbol according to the standard chosen. For more control over the formatting +#' of byte sizes, we can use the following options: +#' \itemize{ +#' \item decimals: choice of the number of decimal places, option to drop +#' trailing zeros, and a choice of the decimal symbol +#' \item digit grouping separators: options to enable/disable digit separators +#' and provide a choice of separator symbol +#' \item pattern: option to use a text pattern for decoration of the formatted +#' values +#' \item locale-based formatting: providing a locale ID will result in number +#' formatting specific to the chosen locale +#' } +#' +#' @inheritParams fmt_number +#' @param standard The way to express large byte sizes. +#' @param decimals An option to specify the exact number of decimal places to +#' use. The default number of decimal places is `1`. +#' @param incl_space An option for whether to include a space between the value +#' and the units. The default of `TRUE` uses a space character for separation. +#' +#' @return An object of class `gt_tbl`. +#' +#' @examples +#' # Use `exibble` to create a gt table; +#' # format the `num` column to have +#' # byte sizes in the binary standard +#' tab_1 <- +#' exibble %>% +#' dplyr::select(num) %>% +#' gt() %>% +#' fmt_bytes(columns = num) +#' +#' # Create a similar table with the +#' # `fmt_bytes()` function, this time +#' # showing byte sizes as binary values +#' tab_2 <- +#' exibble %>% +#' dplyr::select(num) %>% +#' gt() %>% +#' fmt_bytes( +#' columns = num, +#' standard = "binary" +#' ) +#' +#' @family Format Data +#' @section Function ID: +#' 3-5 +#' +#' @import rlang +#' @export +fmt_bytes <- function(data, + columns, + rows = everything(), + standard = c("decimal", "binary"), + decimals = 1, + n_sigfig = NULL, + drop_trailing_zeros = TRUE, + drop_trailing_dec_mark = TRUE, + use_seps = TRUE, + pattern = "{x}", + sep_mark = ",", + dec_mark = ".", + incl_space = TRUE, + locale = NULL) { + + # Perform input object validation + stop_if_not_gt(data = data) + + standard <- match.arg(standard) + + # Use locale-based marks if a locale ID is provided + sep_mark <- get_locale_sep_mark(locale, sep_mark, use_seps) + dec_mark <- get_locale_dec_mark(locale, dec_mark) + + # Set the `formatC_format` option according to whether number + # formatting with significant figures is to be performed + if (!is.null(n_sigfig)) { + + # Stop function if `n_sigfig` does not have a valid value + validate_n_sigfig(n_sigfig) + + formatC_format <- "fg" + } else { + formatC_format <- "f" + } + + if (standard == "decimal") { + base <- 1000 + byte_units <- + c("B", "kB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB") + } else { + base <- 1024 + byte_units <- + c("B", "KiB", "MiB", "GiB", "TiB", "PiB", "EiB", "ZiB", "YiB") + } + + fmt( + data = data, + columns = {{ columns }}, + rows = {{ rows }}, + fns = num_fmt_factory_multi( + pattern = pattern, + format_fn = function(x, context) { + + # Truncate all byte values + x <- trunc(x) + + num_power_idx <- floor(log(abs(x), base = base)) + 1 + num_power_idx <- pmax(1, pmin(length(byte_units), num_power_idx)) + + units_str <- byte_units[num_power_idx] + x <- x / base^(num_power_idx-1) + + x %>% + # Format numeric values to character-based numbers + format_num_to_str( + context = context, decimals = decimals, n_sigfig = n_sigfig, + sep_mark = sep_mark, dec_mark = dec_mark, + drop_trailing_zeros = drop_trailing_zeros, + drop_trailing_dec_mark = drop_trailing_dec_mark, + format = formatC_format + ) %>% + paste_right(paste0(if (incl_space) " ", units_str)) + } + ) + ) +} + #' Format values as dates #' #' Format input date values that are either of the `Date` type, or, are @@ -854,7 +995,7 @@ fmt_currency <- function(data, #' #' @family Format Data #' @section Function ID: -#' 3-5 +#' 3-6 #' #' @import rlang #' @export @@ -983,7 +1124,7 @@ fmt_date <- function(data, #' #' @family Format Data #' @section Function ID: -#' 3-6 +#' 3-7 #' #' @import rlang #' @export @@ -1102,7 +1243,7 @@ fmt_time <- function(data, #' #' @family Format Data #' @section Function ID: -#' 3-7 +#' 3-8 #' #' @import rlang #' @export @@ -1242,7 +1383,7 @@ fmt_datetime <- function(data, #' #' @family Format Data #' @section Function ID: -#' 3-8 +#' 3-9 #' #' @import rlang #' @export @@ -1328,7 +1469,7 @@ fmt_markdown <- function(data, #' #' @family Format Data #' @section Function ID: -#' 3-9 +#' 3-10 #' #' @import rlang #' @export @@ -1461,7 +1602,7 @@ fmt_passthrough <- function(data, #' #' @family Format Data #' @section Function ID: -#' 3-10 +#' 3-11 #' #' @import rlang #' @export @@ -1573,7 +1714,7 @@ fmt_missing <- function(data, #' #' @family Format Data #' @section Function ID: -#' 3-11 +#' 3-12 #' #' @import rlang #' @export diff --git a/R/utils_formatters.R b/R/utils_formatters.R index b159e60de..8c63a72b9 100644 --- a/R/utils_formatters.R +++ b/R/utils_formatters.R @@ -265,6 +265,10 @@ format_num_to_str <- function(x, decimal.mark = dec_mark ) + # Remove `-` for any signed zeros returned by `formatC()` + x_str_signed_zero <- grepl("^(-0|-0\\.0*?)$", x_str) + x_str[x_str_signed_zero] <- gsub("-", "", x_str[x_str_signed_zero]) + # If a trailing decimal mark is to be retained (not the # default option but sometimes desirable), affix the `dec_mark` # to the right of those figures that are missing this mark diff --git a/_pkgdown.yml b/_pkgdown.yml index a150209b4..63c276ae3 100644 --- a/_pkgdown.yml +++ b/_pkgdown.yml @@ -52,6 +52,7 @@ reference: - fmt_scientific - fmt_percent - fmt_currency + - fmt_bytes - fmt_date - fmt_time - fmt_datetime diff --git a/man/data_color.Rd b/man/data_color.Rd index b3af27a4e..f5ba9f0cf 100644 --- a/man/data_color.Rd +++ b/man/data_color.Rd @@ -152,6 +152,7 @@ tab_2 <- } \seealso{ Other Format Data: +\code{\link{fmt_bytes}()}, \code{\link{fmt_currency}()}, \code{\link{fmt_datetime}()}, \code{\link{fmt_date}()}, diff --git a/man/figures/man_fmt_bytes_1.png b/man/figures/man_fmt_bytes_1.png new file mode 100644 index 0000000000000000000000000000000000000000..de7acf27a34f49787c4586d916c44b5c60235b5c GIT binary patch literal 7792 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 100 & [colname_2] < 50}).} + +\item{standard}{The way to express large byte sizes.} + +\item{decimals}{An option to specify the exact number of decimal places to +use. The default number of decimal places is \code{1}.} + +\item{n_sigfig}{A option to format numbers to \emph{n} significant figures. By +default, this is \code{NULL} and thus number values will be formatted according +to the number of decimal places set via \code{decimals}. If opting to format +according to the rules of significant figures, \code{n_sigfig} must be a number +greater than or equal to \code{1}. Any values passed to the \code{decimals} and +\code{drop_trailing_zeros} arguments will be ignored.} + +\item{drop_trailing_zeros}{A logical value that allows for removal of +trailing zeros (those redundant zeros after the decimal mark).} + +\item{drop_trailing_dec_mark}{A logical value that determines whether decimal +marks should always appear even if there are no decimal digits to display +after formatting (e.g, \code{23} becomes \code{23.}). The default for this is \code{TRUE}, +which means that trailing decimal marks are not shown.} + +\item{use_seps}{An option to use digit group separators. The type of digit +group separator is set by \code{sep_mark} and overridden if a locale ID is +provided to \code{locale}. This setting is \code{TRUE} by default.} + +\item{pattern}{A formatting pattern that allows for decoration of the +formatted value. The value itself is represented by \code{{x}} and all other +characters are taken to be string literals.} + +\item{sep_mark}{The mark to use as a separator between groups of digits +(e.g., using \code{sep_mark = ","} with \code{1000} would result in a formatted value +of \verb{1,000}).} + +\item{dec_mark}{The character to use as a decimal mark (e.g., using \code{dec_mark = ","} with \code{0.152} would result in a formatted value of \verb{0,152}).} + +\item{incl_space}{An option for whether to include a space between the value +and the units. The default of \code{TRUE} uses a space character for separation.} + +\item{locale}{An optional locale ID that can be used for formatting the value +according the locale's rules. Examples include \code{"en_US"} for English +(United States) and \code{"fr_FR"} for French (France). The use of a valid +locale ID will override any values provided in \code{sep_mark} and \code{dec_mark}. +We can use the \code{\link[=info_locales]{info_locales()}} function as a useful reference for all of +the locales that are supported.} +} +\value{ +An object of class \code{gt_tbl}. +} +\description{ +With numeric values in a \strong{gt} table, we can transform those to values of +bytes with human readable units. The \code{fmt_bytes()} function allows for the +formatting of byte sizes to either of two common representations: (1) with +decimal units (powers of 1000, examples being \code{"kB"} and \code{"MB"}), and (2) +with binary units (powers of 1024, examples being \code{"KiB"} and \code{"MiB"}). +} +\details{ +It is assumed the input numeric values represent the number of bytes and +automatic truncation of values will occur. The numeric values will be scaled +to be in the range of 1 to <1000 and then decorated with the correct unit +symbol according to the standard chosen. For more control over the formatting +of byte sizes, we can use the following options: +\itemize{ +\item decimals: choice of the number of decimal places, option to drop +trailing zeros, and a choice of the decimal symbol +\item digit grouping separators: options to enable/disable digit separators +and provide a choice of separator symbol +\item pattern: option to use a text pattern for decoration of the formatted +values +\item locale-based formatting: providing a locale ID will result in number +formatting specific to the chosen locale +} +} +\section{Function ID}{ + +3-5 +} + +\examples{ +# Use `exibble` to create a gt table; +# format the `num` column to have +# byte sizes in the binary standard +tab_1 <- + exibble \%>\% + dplyr::select(num) \%>\% + gt() \%>\% + fmt_bytes(columns = num) + +# Create a similar table with the +# `fmt_bytes()` function, this time +# showing byte sizes as binary values +tab_2 <- + exibble \%>\% + dplyr::select(num) \%>\% + gt() \%>\% + fmt_bytes( + columns = num, + standard = "binary" + ) + +} +\seealso{ +Other Format Data: +\code{\link{data_color}()}, +\code{\link{fmt_currency}()}, +\code{\link{fmt_datetime}()}, +\code{\link{fmt_date}()}, +\code{\link{fmt_markdown}()}, +\code{\link{fmt_missing}()}, +\code{\link{fmt_number}()}, +\code{\link{fmt_passthrough}()}, +\code{\link{fmt_percent}()}, +\code{\link{fmt_scientific}()}, +\code{\link{fmt_time}()}, +\code{\link{fmt}()}, +\code{\link{text_transform}()} +} +\concept{Format Data} diff --git a/man/fmt_currency.Rd b/man/fmt_currency.Rd index 51407e321..ec18eddb6 100644 --- a/man/fmt_currency.Rd +++ b/man/fmt_currency.Rd @@ -213,6 +213,7 @@ tab_2 <- \seealso{ Other Format Data: \code{\link{data_color}()}, +\code{\link{fmt_bytes}()}, \code{\link{fmt_datetime}()}, \code{\link{fmt_date}()}, \code{\link{fmt_markdown}()}, diff --git a/man/fmt_date.Rd b/man/fmt_date.Rd index 809580046..7939c9b0c 100644 --- a/man/fmt_date.Rd +++ b/man/fmt_date.Rd @@ -74,7 +74,7 @@ argument. See the Arguments section for more information on this. \section{Function ID}{ -3-5 +3-6 } \examples{ @@ -118,6 +118,7 @@ tab_2 <- \seealso{ Other Format Data: \code{\link{data_color}()}, +\code{\link{fmt_bytes}()}, \code{\link{fmt_currency}()}, \code{\link{fmt_datetime}()}, \code{\link{fmt_markdown}()}, diff --git a/man/fmt_datetime.Rd b/man/fmt_datetime.Rd index 9323f6ef1..d08be631d 100644 --- a/man/fmt_datetime.Rd +++ b/man/fmt_datetime.Rd @@ -92,7 +92,7 @@ argument. See the Arguments section for more information on this. \section{Function ID}{ -3-7 +3-8 } \examples{ @@ -115,6 +115,7 @@ tab_1 <- \seealso{ Other Format Data: \code{\link{data_color}()}, +\code{\link{fmt_bytes}()}, \code{\link{fmt_currency}()}, \code{\link{fmt_date}()}, \code{\link{fmt_markdown}()}, diff --git a/man/fmt_markdown.Rd b/man/fmt_markdown.Rd index 66fdfd136..4d3e31434 100644 --- a/man/fmt_markdown.Rd +++ b/man/fmt_markdown.Rd @@ -45,7 +45,7 @@ argument. See the Arguments section for more information on this. \section{Function ID}{ -3-8 +3-9 } \examples{ @@ -99,6 +99,7 @@ tab_1 <- \seealso{ Other Format Data: \code{\link{data_color}()}, +\code{\link{fmt_bytes}()}, \code{\link{fmt_currency}()}, \code{\link{fmt_datetime}()}, \code{\link{fmt_date}()}, diff --git a/man/fmt_missing.Rd b/man/fmt_missing.Rd index 9af369947..a2519ea6a 100644 --- a/man/fmt_missing.Rd +++ b/man/fmt_missing.Rd @@ -50,7 +50,7 @@ argument. See the Arguments section for more information on this. \section{Function ID}{ -3-10 +3-11 } \examples{ @@ -74,6 +74,7 @@ tab_1 <- \seealso{ Other Format Data: \code{\link{data_color}()}, +\code{\link{fmt_bytes}()}, \code{\link{fmt_currency}()}, \code{\link{fmt_datetime}()}, \code{\link{fmt_date}()}, diff --git a/man/fmt_number.Rd b/man/fmt_number.Rd index 22535a9cc..3958b48c9 100644 --- a/man/fmt_number.Rd +++ b/man/fmt_number.Rd @@ -181,6 +181,7 @@ tab_2 <- \seealso{ Other Format Data: \code{\link{data_color}()}, +\code{\link{fmt_bytes}()}, \code{\link{fmt_currency}()}, \code{\link{fmt_datetime}()}, \code{\link{fmt_date}()}, diff --git a/man/fmt_passthrough.Rd b/man/fmt_passthrough.Rd index 7c2790dda..ab50888e1 100644 --- a/man/fmt_passthrough.Rd +++ b/man/fmt_passthrough.Rd @@ -66,7 +66,7 @@ argument. See the Arguments section for more information on this. \section{Function ID}{ -3-9 +3-10 } \examples{ @@ -89,6 +89,7 @@ tab_1 <- \seealso{ Other Format Data: \code{\link{data_color}()}, +\code{\link{fmt_bytes}()}, \code{\link{fmt_currency}()}, \code{\link{fmt_datetime}()}, \code{\link{fmt_date}()}, diff --git a/man/fmt_percent.Rd b/man/fmt_percent.Rd index f3e899f91..cdb54eae4 100644 --- a/man/fmt_percent.Rd +++ b/man/fmt_percent.Rd @@ -144,6 +144,7 @@ tab_1 <- \seealso{ Other Format Data: \code{\link{data_color}()}, +\code{\link{fmt_bytes}()}, \code{\link{fmt_currency}()}, \code{\link{fmt_datetime}()}, \code{\link{fmt_date}()}, diff --git a/man/fmt_scientific.Rd b/man/fmt_scientific.Rd index cd902f850..c12873d71 100644 --- a/man/fmt_scientific.Rd +++ b/man/fmt_scientific.Rd @@ -42,9 +42,7 @@ use. The default number of decimal places is \code{2}.} trailing zeros (those redundant zeros after the decimal mark).} \item{scale_by}{A value to scale the input. The default is \code{1.0}. All numeric -values will be multiplied by this value first before undergoing formatting. -This value will be ignored if using any of the \code{suffixing} options (i.e., -where \code{suffixing} is not set to \code{FALSE}).} +values will be multiplied by this value first before undergoing formatting.} \item{pattern}{A formatting pattern that allows for decoration of the formatted value. The value itself is represented by \code{{x}} and all other @@ -122,6 +120,7 @@ tab_1 <- \seealso{ Other Format Data: \code{\link{data_color}()}, +\code{\link{fmt_bytes}()}, \code{\link{fmt_currency}()}, \code{\link{fmt_datetime}()}, \code{\link{fmt_date}()}, diff --git a/man/fmt_time.Rd b/man/fmt_time.Rd index 699494314..73e5282be 100644 --- a/man/fmt_time.Rd +++ b/man/fmt_time.Rd @@ -64,7 +64,7 @@ argument. See the Arguments section for more information on this. \section{Function ID}{ -3-6 +3-7 } \examples{ @@ -108,6 +108,7 @@ tab_2 <- \seealso{ Other Format Data: \code{\link{data_color}()}, +\code{\link{fmt_bytes}()}, \code{\link{fmt_currency}()}, \code{\link{fmt_datetime}()}, \code{\link{fmt_date}()}, diff --git a/man/text_transform.Rd b/man/text_transform.Rd index 81b3f1a93..746c7cb89 100644 --- a/man/text_transform.Rd +++ b/man/text_transform.Rd @@ -65,6 +65,7 @@ tab_1 <- \seealso{ Other Format Data: \code{\link{data_color}()}, +\code{\link{fmt_bytes}()}, \code{\link{fmt_currency}()}, \code{\link{fmt_datetime}()}, \code{\link{fmt_date}()}, diff --git a/tests/testthat/test-fmt_bytes.R b/tests/testthat/test-fmt_bytes.R new file mode 100644 index 000000000..96d60faa7 --- /dev/null +++ b/tests/testthat/test-fmt_bytes.R @@ -0,0 +1,433 @@ +test_that("the `fmt_bytes()` function works correctly", { + + # Create an input data frame two columns: one + # character-based and one that is numeric + data_tbl <- + data.frame( + char = "a", + num = c( + -500, # "-500 B" + -0.9, 0, 0.9, # All should be "0 B" + 500, # "500 B" + 1023, + 1001, + 1024, # 1 kB binary + 1048576, # 1 MB '' + 1073741824, # 1 GB '' + 1099511627776, # 1 TB '' + 1125899906842624, # 1 PB '' + 1152921504606846976, # 1 EB '' + 1180591620717411303424, # 1 ZB '' + 1208925819614629174706176, # 1 YB '' + 10^(c(3, 6, 9, 12, 15, 18, 21, 24)), # 1 KiB ... 1 YiB decimal + 15000000000000000000000000, + 150000000000000000000000000, + 1500000000000000000000000000, + 15000000000000000000000000000, + NA + ), + stringsAsFactors = FALSE + ) + + # Create a `gt_tbl` object with `gt()` and the + # `data_tbl` dataset + tab <- gt(data = data_tbl) + + # Expect that the object has the correct classes + expect_is(tab, c("gt_tbl", "data.frame")) + + # Extract vectors from the table object for comparison + # to the original dataset + char <- (tab %>% dt_data_get())[["char"]] + num <- (tab %>% dt_data_get())[["num"]] + + # Expect the extracted values to match those of the + # original dataset + expect_equal(data_tbl$char, char) + expect_equal(data_tbl$num, num) + + # Expect an error when attempting to format a column + # that does not exist + expect_error(tab %>% fmt_bytes(columns = num_2, decimals = 2)) + + # Expect an error when using a locale that does not exist + expect_error(tab %>% fmt_bytes(columns = num_2, decimals = 2, locale = "aa_bb")) + + # Format the `num` column to 1 decimal place, use all + # other defaults; extract `output_df` and compare to expected values + expect_equal( + (tab %>% + fmt_bytes(columns = num, decimals = 1) %>% + render_formats_test(context = "html"))[["num"]], + c( + "−500 B", "0 B", "0 B", "0 B", "500 B", "1 kB", "1 kB", + "1 kB", "1 MB", "1.1 GB", "1.1 TB", "1.1 PB", "1.2 EB", "1.2 ZB", + "1.2 YB", "1 kB", "1 MB", "1 GB", "1 TB", "1 PB", "1 EB", "1 ZB", + "1 YB", "15 YB", "150 YB", "1,500 YB", "15,000 YB", "NA" + ) + ) + + # Format the `num` column to 4 decimal places, use all + # other defaults; extract `output_df` and compare to expected values + expect_equal( + (tab %>% + fmt_bytes(columns = num, decimals = 4) %>% + render_formats_test("html"))[["num"]], + c( + "−500 B", "0 B", "0 B", "0 B", "500 B", "1.023 kB", "1.001 kB", + "1.024 kB", "1.0486 MB", "1.0737 GB", "1.0995 TB", "1.1259 PB", + "1.1529 EB", "1.1806 ZB", "1.2089 YB", "1 kB", "1 MB", "1 GB", + "1 TB", "1 PB", "1 EB", "1 ZB", "1 YB", "15 YB", "150 YB", "1,500 YB", + "15,000 YB", "NA" + ) + ) + + # Format the `num` column to 2 decimal places, keep the trailing + # zeros, use all other defaults; extract `output_df` and compare to + # expected values + expect_equal( + (tab %>% + fmt_bytes( + columns = num, decimals = 2, + drop_trailing_zeros = FALSE + ) %>% + render_formats_test("html"))[["num"]], + c( + "−500.00 B", "0.00 B", "0.00 B", "0.00 B", "500.00 B", + "1.02 kB", "1.00 kB", "1.02 kB", "1.05 MB", "1.07 GB", "1.10 TB", + "1.13 PB", "1.15 EB", "1.18 ZB", "1.21 YB", "1.00 kB", "1.00 MB", + "1.00 GB", "1.00 TB", "1.00 PB", "1.00 EB", "1.00 ZB", "1.00 YB", + "15.00 YB", "150.00 YB", "1,500.00 YB", "15,000.00 YB", "NA" + ) + ) + + # Format the `num` column to 2 decimal places, keep the trailing + # zeros, express byte sizes in the binary standard; extract `output_df` + # and compare to expected values + expect_equal( + (tab %>% + fmt_bytes( + columns = num, standard = "binary", decimals = 2, + drop_trailing_zeros = FALSE + ) %>% + render_formats_test("html"))[["num"]], + c( + "−500.00 B", "0.00 B", "0.00 B", "0.00 B", "500.00 B", + "1,023.00 B", "1,001.00 B", "1.00 KiB", "1.00 MiB", "1.00 GiB", + "1.00 TiB", "1.00 PiB", "1.00 EiB", "1.00 ZiB", "1.00 YiB", "1,000.00 B", + "976.56 KiB", "953.67 MiB", "931.32 GiB", "909.49 TiB", "888.18 PiB", + "867.36 EiB", "847.03 ZiB", "12.41 YiB", "124.08 YiB", "1,240.77 YiB", + "12,407.71 YiB", "NA" + ) + ) + + # Format the `num` column to 1 decimal place, don't use digit + # grouping separators, use all other defaults; extract `output_df` + # and compare to expected values + expect_equal( + (tab %>% + fmt_bytes(columns = num, use_seps = FALSE) %>% + render_formats_test("html"))[["num"]], + c( + "−500 B", "0 B", "0 B", "0 B", "500 B", "1 kB", "1 kB", + "1 kB", "1 MB", "1.1 GB", "1.1 TB", "1.1 PB", "1.2 EB", "1.2 ZB", + "1.2 YB", "1 kB", "1 MB", "1 GB", "1 TB", "1 PB", "1 EB", "1 ZB", + "1 YB", "15 YB", "150 YB", "1500 YB", "15000 YB", "NA" + ) + ) + + # Format the `num` column to 2 decimal places, use a single space + # character as digit grouping separators, use all other defaults; + # extract `output_df` and compare to expected values + expect_equal( + (tab %>% + fmt_bytes(columns = num, decimals = 2, sep_mark = " ") %>% + render_formats_test("html"))[["num"]], + c( + "−500 B", "0 B", "0 B", "0 B", "500 B", "1.02 kB", "1 kB", + "1.02 kB", "1.05 MB", "1.07 GB", "1.1 TB", "1.13 PB", "1.15 EB", + "1.18 ZB", "1.21 YB", "1 kB", "1 MB", "1 GB", "1 TB", "1 PB", + "1 EB", "1 ZB", "1 YB", "15 YB", "150 YB", "1 500 YB", "15 000 YB", + "NA" + ) + ) + + # Format the `num` column to 2 decimal places, don't use a space between + # the numeric value and the units, use all other defaults; + # extract `output_df` and compare to expected values + expect_equal( + (tab %>% + fmt_bytes(columns = num, decimals = 2, incl_space = FALSE) %>% + render_formats_test("html"))[["num"]], + c( + "−500B", "0B", "0B", "0B", "500B", "1.02kB", "1kB", "1.02kB", + "1.05MB", "1.07GB", "1.1TB", "1.13PB", "1.15EB", "1.18ZB", "1.21YB", + "1kB", "1MB", "1GB", "1TB", "1PB", "1EB", "1ZB", "1YB", "15YB", + "150YB", "1,500YB", "15,000YB", "NA" + ) + ) + + # Format the `num` column to 2 decimal places, use a period for the + # digit grouping separators and a comma for the decimal mark, use + # all other defaults; extract `output_df` and compare to expected values + expect_equal( + (tab %>% + fmt_bytes( + columns = num, decimals = 2, sep_mark = ".", dec_mark = "," + ) %>% + render_formats_test("html"))[["num"]], + c( + "−500 B", "0 B", "0 B", "0 B", "500 B", "1,02 kB", "1 kB", + "1,02 kB", "1,05 MB", "1,07 GB", "1,1 TB", "1,13 PB", "1,15 EB", + "1,18 ZB", "1,21 YB", "1 kB", "1 MB", "1 GB", "1 TB", "1 PB", + "1 EB", "1 ZB", "1 YB", "15 YB", "150 YB", "1.500 YB", "15.000 YB", + "NA" + ) + ) + + # Format the `num` column to 2 decimal places, prepend and append + # all values by 2 different literals, use all other defaults; extract + # `output_df` and compare to expected values + expect_equal( + (tab %>% + fmt_bytes(columns = num, decimals = 2, pattern = "a {x} b") %>% + render_formats_test("html"))[["num"]], + c( + "a −500 B b", "a 0 B b", "a 0 B b", "a 0 B b", "a 500 B b", + "a 1.02 kB b", "a 1 kB b", "a 1.02 kB b", "a 1.05 MB b", "a 1.07 GB b", + "a 1.1 TB b", "a 1.13 PB b", "a 1.15 EB b", "a 1.18 ZB b", "a 1.21 YB b", + "a 1 kB b", "a 1 MB b", "a 1 GB b", "a 1 TB b", "a 1 PB b", "a 1 EB b", + "a 1 ZB b", "a 1 YB b", "a 15 YB b", "a 150 YB b", "a 1,500 YB b", + "a 15,000 YB b", "NA" + ) + ) + + # Format the `num` column to 2 decimal places, apply the `en_US` + # locale and use all other defaults; extract `output_df` and compare + # to expected values + expect_equal( + (tab %>% + fmt_bytes(columns = num, decimals = 2, locale = "en_US") %>% + render_formats_test("html"))[["num"]], + c( + "−500 B", "0 B", "0 B", "0 B", "500 B", "1.02 kB", "1 kB", + "1.02 kB", "1.05 MB", "1.07 GB", "1.1 TB", "1.13 PB", "1.15 EB", + "1.18 ZB", "1.21 YB", "1 kB", "1 MB", "1 GB", "1 TB", "1 PB", + "1 EB", "1 ZB", "1 YB", "15 YB", "150 YB", "1,500 YB", "15,000 YB", + "NA" + ) + ) + + # Format the `num` column to 2 decimal places, apply the `da_DK` + # locale and use all other defaults; extract `output_df` and compare + # to expected values + expect_equal( + (tab %>% + fmt_bytes(columns = num, decimals = 2, locale = "da_DK") %>% + render_formats_test("html"))[["num"]], + c( + "−500 B", "0 B", "0 B", "0 B", "500 B", "1,02 kB", "1 kB", + "1,02 kB", "1,05 MB", "1,07 GB", "1,1 TB", "1,13 PB", "1,15 EB", + "1,18 ZB", "1,21 YB", "1 kB", "1 MB", "1 GB", "1 TB", "1 PB", + "1 EB", "1 ZB", "1 YB", "15 YB", "150 YB", "1.500 YB", "15.000 YB", + "NA" + ) + ) + + # Format the `num` column to 2 decimal places, apply the `de_AT` + # locale and use all other defaults; extract `output_df` and compare + # to expected values + expect_equal( + (tab %>% + fmt_bytes(columns = num, decimals = 2, locale = "de_AT") %>% + render_formats_test("html"))[["num"]], + c( + "−500 B", "0 B", "0 B", "0 B", "500 B", "1,02 kB", "1 kB", + "1,02 kB", "1,05 MB", "1,07 GB", "1,1 TB", "1,13 PB", "1,15 EB", + "1,18 ZB", "1,21 YB", "1 kB", "1 MB", "1 GB", "1 TB", "1 PB", + "1 EB", "1 ZB", "1 YB", "15 YB", "150 YB", "1 500 YB", "15 000 YB", + "NA" + ) + ) + + # Format the `num` column to 2 decimal places, apply the `et_EE` + # locale and use all other defaults; extract `output_df` and compare + # to expected values + expect_equal( + (tab %>% + fmt_bytes(columns = num, decimals = 2, locale = "et_EE") %>% + render_formats_test("html"))[["num"]], + c( + "−500 B", "0 B", "0 B", "0 B", "500 B", "1,02 kB", "1 kB", + "1,02 kB", "1,05 MB", "1,07 GB", "1,1 TB", "1,13 PB", "1,15 EB", + "1,18 ZB", "1,21 YB", "1 kB", "1 MB", "1 GB", "1 TB", "1 PB", + "1 EB", "1 ZB", "1 YB", "15 YB", "150 YB", "1 500 YB", "15 000 YB", + "NA" + ) + ) + + # Format the `num` column to 2 decimal places, apply the `gl_ES` + # locale and use all other defaults; extract `output_df` and compare + # to expected values + expect_equal( + (tab %>% + fmt_bytes(columns = num, decimals = 2, locale = "gl_ES") %>% + render_formats_test("html"))[["num"]], + c( + "−500 B", "0 B", "0 B", "0 B", "500 B", "1,02 kB", "1 kB", + "1,02 kB", "1,05 MB", "1,07 GB", "1,1 TB", "1,13 PB", "1,15 EB", + "1,18 ZB", "1,21 YB", "1 kB", "1 MB", "1 GB", "1 TB", "1 PB", + "1 EB", "1 ZB", "1 YB", "15 YB", "150 YB", "1.500 YB", "15.000 YB", + "NA" + ) + ) + + # Expect that a column with NAs will work fine with `fmt_bytes()`, + # it'll just produce NA values + na_col_tbl <- dplyr::tibble(a = rep(NA_real_, 10), b = 1:10) %>% gt() + + # Expect a returned object of class `gt_tbl` with various + # uses of `fmt_bytes()` + expect_error( + regexp = NA, + na_col_tbl %>% fmt_bytes(columns = a) %>% as_raw_html() + ) + expect_error( + regexp = NA, + na_col_tbl %>% + fmt_bytes(columns = a, rows = 1:5) %>% as_raw_html() + ) + expect_error( + regexp = NA, + na_col_tbl %>% + fmt_bytes(columns = a, pattern = "a{x}b", incl_space = FALSE) %>% as_raw_html() + ) + + # Expect that two columns being formatted (one entirely NA) will work + expect_equal( + (na_col_tbl %>% + fmt_bytes(columns = a) %>% + fmt_bytes(columns = b) %>% render_formats_test("html"))[["b"]], + c("1 B", "2 B", "3 B", "4 B", "5 B", "6 B", "7 B", "8 B", "9 B", "10 B") + ) +}) + +test_that("the `fmt_bytes()` function format to specified significant figures", { + + # These numbers will be used in tests of formatting + # correctly to n significant figures + numbers <- + c( + 50000.01, #1 + 1000.001, #2 + 10.00001, #3 + 12345, #4 + 1234.5, #5 + 123.45, #6 + 1.2345, #7 + 0.12345, #8 + 0.0000123456, #9 + -50000.01, #10 + -1000.001, #11 + -10.00001, #12 + -12345, #13 + -1234.5, #14 + -123.45, #15 + -1.2345, #16 + -0.12345, #17 + -0.0000123456 #18 + ) + + # Create a single-column tibble with these values in `num` + numbers_tbl <- dplyr::tibble(num = numbers) + + # Create a `gt_tbl` object with `gt()` and the + # `numbers_tbl` dataset + tab <- gt(data = numbers_tbl) + + # Format the `num` column to 5 significant figures + expect_equal( + (tab %>% + fmt_bytes(columns = num, n_sigfig = 5) %>% + render_formats_test(context = "html"))[["num"]], + c( + "50.000 kB", "1.0000 kB", "10.000 B", "12.345 kB", "1.2340 kB", + "123.00 B", "1.0000 B", "0 B", "0 B", "−50.000 kB", "−1.0000 kB", + "−10.000 B", "−12.345 kB", "−1.2340 kB", "−123.00 B", + "−1.0000 B", "0 B", "0 B" + ) + ) + + # Format the `num` column to 4 significant figures + expect_equal( + (tab %>% + fmt_bytes(columns = num, n_sigfig = 4) %>% + render_formats_test(context = "html"))[["num"]], + c( + "50.00 kB", "1.000 kB", "10.00 B", "12.34 kB", "1.234 kB", + "123.0 B", "1.000 B", "0 B", "0 B", "−50.00 kB", "−1.000 kB", + "−10.00 B", "−12.34 kB", "−1.234 kB", "−123.0 B", + "−1.000 B", "0 B", "0 B" + ) + ) + + # Format the `num` column to 3 significant figures + expect_equal( + (tab %>% + fmt_bytes(columns = num, n_sigfig = 3) %>% + render_formats_test(context = "html"))[["num"]], + c( + "50.0 kB", "1.00 kB", "10.0 B", "12.3 kB", "1.23 kB", "123 B", + "1.00 B", "0 B", "0 B", "−50.0 kB", "−1.00 kB", "−10.0 B", + "−12.3 kB", "−1.23 kB", "−123 B", "−1.00 B", + "0 B", "0 B" + ) + ) + + # Format the `num` column to 2 significant figures + expect_equal( + (tab %>% + fmt_bytes(columns = num, n_sigfig = 2) %>% + render_formats_test(context = "html"))[["num"]], + c( + "50 kB", "1.0 kB", "10 B", "12 kB", "1.2 kB", "120 B", "1.0 B", + "0 B", "0 B", "−50 kB", "−1.0 kB", "−10 B", + "−12 kB", "−1.2 kB", "−120 B", "−1.0 B", + "0 B", "0 B" + ) + ) + + # Format the `num` column to 1 significant figure + expect_equal( + (tab %>% + fmt_bytes(columns = num, n_sigfig = 1) %>% + render_formats_test(context = "html"))[["num"]], + c( + "50 kB", "1 kB", "10 B", "10 kB", "1 kB", "100 B", "1 B", "0 B", + "0 B", "−50 kB", "−1 kB", "−10 B", "−10 kB", + "−1 kB", "−100 B", "−1 B", "0 B", "0 B" + ) + ) + + # Expect an error if the length of `n_sigfig` is not 1 + expect_error(fmt_bytes(columns = num, n_sigfig = c(1, 2))) + + # Expect an error if `n_sigfig` is NA + expect_error(tab %>% fmt_bytes(columns = num, n_sigfig = NA)) + expect_error(tab %>% fmt_bytes(columns = num, n_sigfig = NA_integer_)) + expect_error(tab %>% fmt_bytes(columns = num, n_sigfig = NA_real_)) + expect_error(tab %>% fmt_bytes(columns = num, n_sigfig = NA_integer_)) + + # Expect an error if `n_sigfig` is not numeric + expect_error(tab %>% fmt_bytes(columns = num, n_sigfig = "3")) + expect_error(tab %>% fmt_bytes(columns = num, n_sigfig = TRUE)) + expect_error(tab %>% fmt_bytes(columns = num, n_sigfig = factor(3))) + + # Don't expect errors when using integers or doubles + expect_error(regexp = NA, tab %>% fmt_bytes(columns = num, n_sigfig = 2L)) + expect_error(regexp = NA, tab %>% fmt_bytes(columns = num, n_sigfig = 2)) + + # Expect an error if `n_sigfig` is less than 1 + expect_error(tab %>% fmt_bytes(columns = num, n_sigfig = 0L)) + expect_error(tab %>% fmt_bytes(columns = num, n_sigfig = -1L)) +}) From 0ded026809306e0e8497f28cfe09404574659f32 Mon Sep 17 00:00:00 2001 From: Richard Iannone Date: Wed, 5 May 2021 14:23:37 -0400 Subject: [PATCH 08/24] Simplify arguments for RTF page numbering --- R/export.R | 37 ++++++++------------- R/utils_render_rtf.R | 9 +++-- man/as_rtf.Rd | 18 +++------- man/gtsave.Rd | 7 ++-- tests/testthat/_snaps/rtf_page_numbering.md | 6 ++-- tests/testthat/test-rtf_page_numbering.R | 6 ++-- 6 files changed, 29 insertions(+), 54 deletions(-) diff --git a/R/export.R b/R/export.R index f66b4cda1..b3801c1bd 100644 --- a/R/export.R +++ b/R/export.R @@ -14,10 +14,10 @@ #' of these arguments. #' #' If the output filename is expressed with the `.rtf` extension then an RTF -#' file will be generated. In this case, there two options that can be passed -#' through `...`: `page_numbering.active` and `page_numbering.location`. Both of -#' these options control RTF document page numbering and, by default, page -#' numbering is not activated (i.e., `page_numbering.active = FALSE`). +#' file will be generated. In this case, there is an option that can be passed +#' through `...`: `page_numbering`. This controls RTF document page numbering +#' and, by default, page numbering is not enabled (i.e., `page_numbering = +#' "none"`). #' #' We can create an image file based on the HTML version of the `gt` table. With #' the filename extension `.png`, we get a PNG image file. A PDF document can be @@ -238,18 +238,14 @@ gt_save_rtf <- function(data, filename, path = NULL, ..., - page_numbering.active = FALSE, - page_numbering.location = c("footer", "header")) { + page_numbering = c("none", "footer", "header")) { - page_numbering.location <- match.arg(page_numbering.location) + page_numbering <- match.arg(page_numbering) filename <- gtsave_filename(path = path, filename = filename) data %>% - as_rtf( - page_numbering.active = page_numbering.active, - page_numbering.location = page_numbering.location - ) %>% + as_rtf(page_numbering = page_numbering) %>% writeLines(con = filename) } @@ -452,14 +448,9 @@ as_latex <- function(data) { #' file that can be opened by RTF readers. #' #' @param data A table object that is created using the `gt()` function. -#' @param page_numbering.active An option to include page numbering in the RTF -#' document. The location for page numbering text is either in the document -#' footer or header (governed by the `page_numbering.location` option). By -#' default, page numbering is not active (`FALSE`). -#' @param page_numbering.location If `page_numbering.active` is `TRUE` then this -#' option determines where the page numbering text will be placed. It will -#' either be in the RTF document `"footer"` (default option) or the -#' `"header"`. +#' @param page_numbering An option to include page numbering in the RTF +#' document. The page numbering text can either be in the document `"footer"` +#' or `"header"`. By default, page numbering is not active (`"none"`). #' #' @examples #' # Use `gtcars` to create a gt table; @@ -482,10 +473,9 @@ as_latex <- function(data) { #' #' @export as_rtf <- function(data, - page_numbering.active = FALSE, - page_numbering.location = c("footer", "header")) { + page_numbering = c("none", "footer", "header")) { - page_numbering.location <- match.arg(page_numbering.location) + page_numbering <- match.arg(page_numbering) # Perform input object validation stop_if_not_gt(data = data) @@ -524,8 +514,7 @@ as_rtf <- function(data, ) ) }, - page_numbering.active = page_numbering.active, - page_numbering.location = page_numbering.location + page_numbering = page_numbering ) %>% as_rtf_string() diff --git a/R/utils_render_rtf.R b/R/utils_render_rtf.R index 6c9274209..f689b0bd2 100644 --- a/R/utils_render_rtf.R +++ b/R/utils_render_rtf.R @@ -183,8 +183,7 @@ rtf_header <- function(..., .charset = "ansi", .ansi_code_page = 1252) { rtf_file <- function(header = NULL, document = NULL, - page_numbering.active, - page_numbering.location) { + page_numbering) { if (is.null(header) && is.null(document)) { header <- document <- "" @@ -231,8 +230,8 @@ rtf_file <- function(header = NULL, header <- rtf_header(fonttbl, colortbl) } - # Include RTF code to express page numbering if `page_numbering.active = TRUE` - if (page_numbering.active) { + # Include RTF code to express page numbering if `page_numbering != "none"` + if (page_numbering != "none") { document <- paste( @@ -240,7 +239,7 @@ rtf_file <- function(header = NULL, "\n\n", rtf_raw( "{", - if (page_numbering.location == "footer") "\\footer" else "\\header", + if (page_numbering == "footer") "\\footer" else "\\header", "\\qr{\n{\\field{\\*\\fldinst {PAGE}}{\\fldrslt {Refresh >F9<}}}}\\par}" ) ) diff --git a/man/as_rtf.Rd b/man/as_rtf.Rd index 5adead464..5cd77b670 100644 --- a/man/as_rtf.Rd +++ b/man/as_rtf.Rd @@ -4,24 +4,14 @@ \alias{as_rtf} \title{Output a \strong{gt} object as RTF} \usage{ -as_rtf( - data, - page_numbering.active = FALSE, - page_numbering.location = c("footer", "header") -) +as_rtf(data, page_numbering = c("none", "footer", "header")) } \arguments{ \item{data}{A table object that is created using the \code{gt()} function.} -\item{page_numbering.active}{An option to include page numbering in the RTF -document. The location for page numbering text is either in the document -footer or header (governed by the \code{page_numbering.location} option). By -default, page numbering is not active (\code{FALSE}).} - -\item{page_numbering.location}{If \code{page_numbering.active} is \code{TRUE} then this -option determines where the page numbering text will be placed. It will -either be in the RTF document \code{"footer"} (default option) or the -\code{"header"}.} +\item{page_numbering}{An option to include page numbering in the RTF +document. The page numbering text can either be in the document \code{"footer"} +or \code{"header"}. By default, page numbering is not active (\code{"none"}).} } \description{ Get the RTF content from a \code{gt_tbl} object as as a single-element character diff --git a/man/gtsave.Rd b/man/gtsave.Rd index cb1a81b63..3f89f54f2 100644 --- a/man/gtsave.Rd +++ b/man/gtsave.Rd @@ -36,10 +36,9 @@ please refer to the \strong{htmltools} documentation for more details on the use of these arguments. If the output filename is expressed with the \code{.rtf} extension then an RTF -file will be generated. In this case, there two options that can be passed -through \code{...}: \code{page_numbering.active} and \code{page_numbering.location}. Both of -these options control RTF document page numbering and, by default, page -numbering is not activated (i.e., \code{page_numbering.active = FALSE}). +file will be generated. In this case, there is an option that can be passed +through \code{...}: \code{page_numbering}. This controls RTF document page numbering +and, by default, page numbering is not enabled (i.e., \code{page_numbering = "none"}). We can create an image file based on the HTML version of the \code{gt} table. With the filename extension \code{.png}, we get a PNG image file. A PDF document can be diff --git a/tests/testthat/_snaps/rtf_page_numbering.md b/tests/testthat/_snaps/rtf_page_numbering.md index 12fa4080d..819603c60 100644 --- a/tests/testthat/_snaps/rtf_page_numbering.md +++ b/tests/testthat/_snaps/rtf_page_numbering.md @@ -177,8 +177,7 @@ {\footer\qr{ - Page {\field{\*\fldinst {PAGE}}{\fldrslt {Refresh >F9<}}} of {\field{\*\fldinst {SECTIONPAGES}}{\fldrslt {Refresh >F9<}}} - }\par}} + {\field{\*\fldinst {PAGE}}{\fldrslt {Refresh >F9<}}}}\par}} --- @@ -270,6 +269,5 @@ {\header\qr{ - Page {\field{\*\fldinst {PAGE}}{\fldrslt {Refresh >F9<}}} of {\field{\*\fldinst {SECTIONPAGES}}{\fldrslt {Refresh >F9<}}} - }\par}} + {\field{\*\fldinst {PAGE}}{\fldrslt {Refresh >F9<}}}}\par}} diff --git a/tests/testthat/test-rtf_page_numbering.R b/tests/testthat/test-rtf_page_numbering.R index 73ae0e034..ed63d7aef 100644 --- a/tests/testthat/test-rtf_page_numbering.R +++ b/tests/testthat/test-rtf_page_numbering.R @@ -11,15 +11,15 @@ test_that("page numbering directives can be added to RTF documents", { as_rtf() %>% expect_snapshot() - # Expect for there to be page numbering code for the footer by default + # Expect for there to be page numbering code for the footer exibble_min %>% gt() %>% - as_rtf(page_numbering.active = TRUE) %>% + as_rtf(page_numbering = "footer") %>% expect_snapshot() # Expect for there to be page numbering code for the header exibble_min %>% gt() %>% - as_rtf(page_numbering.active = TRUE, page_numbering.location = "header") %>% + as_rtf(page_numbering = "header") %>% expect_snapshot() }) From 405f63b8b7c880495f9eeb634647af607bfa5b4a Mon Sep 17 00:00:00 2001 From: Richard Iannone Date: Fri, 7 May 2021 14:48:25 -0400 Subject: [PATCH 09/24] Add `accounting` options for `fmt_percent()` and `fmt_number()` (#756) * Enable the `accounting` option in more formatters * Update help files using roxygen * Update several testthat tests * Clean up formatting of testthat tests * Remove unneeded statement * Provide early return in `format_as_accounting()` Co-authored-by: Joe Cheng --- R/format_data.R | 23 +- R/utils_formatters.R | 24 +-- man/fmt_currency.Rd | 10 +- man/fmt_number.Rd | 5 + man/fmt_percent.Rd | 5 + tests/testthat/test-fmt_number.R | 319 ++++++++++++++++++---------- tests/testthat/test-fmt_percent.R | 224 ++++++++++++------- tests/testthat/test-l_fmt_number.R | 206 +++++++++++------- tests/testthat/test-l_fmt_percent.R | 166 +++++++++++---- 9 files changed, 647 insertions(+), 335 deletions(-) diff --git a/R/format_data.R b/R/format_data.R index 22d87842e..6fbae0bcb 100644 --- a/R/format_data.R +++ b/R/format_data.R @@ -55,6 +55,9 @@ #' @param use_seps An option to use digit group separators. The type of digit #' group separator is set by `sep_mark` and overridden if a locale ID is #' provided to `locale`. This setting is `TRUE` by default. +#' @param accounting An option to use accounting style for values. With `FALSE` +#' (the default), negative values will be shown with a minus sign. Using +#' `accounting = TRUE` will put negative values in parentheses. #' @param scale_by A value to scale the input. The default is `1.0`. All numeric #' values will be multiplied by this value first before undergoing formatting. #' This value will be ignored if using any of the `suffixing` options (i.e., @@ -148,6 +151,7 @@ fmt_number <- function(data, drop_trailing_zeros = FALSE, drop_trailing_dec_mark = TRUE, use_seps = TRUE, + accounting = FALSE, scale_by = 1.0, suffixing = FALSE, pattern = "{x}", @@ -201,7 +205,8 @@ fmt_number <- function(data, # Create the `suffix_df` object suffix_df <- create_suffix_df(x, decimals, suffix_labels, scale_by) - x %>% + x_str <- + x %>% # Scale the `x_vals` by the `scale_by` values scale_x_values(suffix_df$scale_by) %>% # Format numeric values to character-based numbers @@ -215,6 +220,14 @@ fmt_number <- function(data, # With large-number suffixing support, we paste the # vector of suffixes to the right of the values paste_right(suffix_df$suffix) + + x_str <- + x_str %>% + format_as_accounting( + x = x, context = context, accounting = accounting + ) + + x_str } ) ) @@ -556,6 +569,7 @@ fmt_percent <- function(data, drop_trailing_dec_mark = TRUE, scale_values = TRUE, use_seps = TRUE, + accounting = FALSE, pattern = "{x}", sep_mark = ",", dec_mark = ".", @@ -584,7 +598,7 @@ fmt_percent <- function(data, columns = {{ columns }}, rows = {{ rows }}, symbol = "%", - accounting = FALSE, + accounting = accounting, decimals = decimals, drop_trailing_zeros = drop_trailing_zeros, drop_trailing_dec_mark = drop_trailing_dec_mark, @@ -661,9 +675,6 @@ fmt_percent <- function(data, #' used. #' @param use_subunits An option for whether the subunits portion of a currency #' value should be displayed. By default, this is `TRUE`. -#' @param accounting An option to use accounting style for currency values. With -#' `FALSE` (the default), negative values will be shown with a minus sign. -#' Using `accounting = TRUE` will put negative values in parentheses. #' @param placement The placement of the currency symbol. This can be either be #' `left` (the default) or `right`. #' @param incl_space An option for whether to include a space between the value @@ -716,10 +727,10 @@ fmt_currency <- function(data, rows = everything(), currency = "USD", use_subunits = TRUE, - accounting = FALSE, decimals = NULL, drop_trailing_dec_mark = TRUE, use_seps = TRUE, + accounting = FALSE, scale_by = 1.0, suffixing = FALSE, pattern = "{x}", diff --git a/R/utils_formatters.R b/R/utils_formatters.R index 8c63a72b9..d8687958e 100644 --- a/R/utils_formatters.R +++ b/R/utils_formatters.R @@ -599,6 +599,10 @@ format_as_accounting <- function(x_str, context, accounting) { + if (!accounting) { + return(x_str) + } + # TODO: Handle using `x_abs_str` instead # Store logical vector of `x` < 0 @@ -609,19 +613,15 @@ format_as_accounting <- function(x_str, return(x_str) } - # Handle case where negative values are to be placed within parentheses - if (accounting) { - - # Create the minus and parens marks for the context - minus_mark <- context_minus_mark(context) - parens_marks <- context_parens_marks(context) + # Create the minus and parens marks for the context + minus_mark <- context_minus_mark(context) + parens_marks <- context_parens_marks(context) - # Selectively remove minus sign and paste between parentheses - x_str[x_lt0] <- - x_str[x_lt0] %>% - tidy_gsub(minus_mark, "", fixed = TRUE) %>% - paste_between(x_2 = parens_marks) - } + # Selectively remove minus sign and paste between parentheses + x_str[x_lt0] <- + x_str[x_lt0] %>% + tidy_gsub(minus_mark, "", fixed = TRUE) %>% + paste_between(x_2 = parens_marks) x_str } diff --git a/man/fmt_currency.Rd b/man/fmt_currency.Rd index ec18eddb6..ab76e0052 100644 --- a/man/fmt_currency.Rd +++ b/man/fmt_currency.Rd @@ -10,10 +10,10 @@ fmt_currency( rows = everything(), currency = "USD", use_subunits = TRUE, - accounting = FALSE, decimals = NULL, drop_trailing_dec_mark = TRUE, use_seps = TRUE, + accounting = FALSE, scale_by = 1, suffixing = FALSE, pattern = "{x}", @@ -65,10 +65,6 @@ used.} \item{use_subunits}{An option for whether the subunits portion of a currency value should be displayed. By default, this is \code{TRUE}.} -\item{accounting}{An option to use accounting style for currency values. With -\code{FALSE} (the default), negative values will be shown with a minus sign. -Using \code{accounting = TRUE} will put negative values in parentheses.} - \item{decimals}{An option to specify the exact number of decimal places to use. The default number of decimal places is \code{2}.} @@ -81,6 +77,10 @@ which means that trailing decimal marks are not shown.} group separator is set by \code{sep_mark} and overridden if a locale ID is provided to \code{locale}. This setting is \code{TRUE} by default.} +\item{accounting}{An option to use accounting style for values. With \code{FALSE} +(the default), negative values will be shown with a minus sign. Using +\code{accounting = TRUE} will put negative values in parentheses.} + \item{scale_by}{A value to scale the input. The default is \code{1.0}. All numeric values will be multiplied by this value first before undergoing formatting. This value will be ignored if using any of the \code{suffixing} options (i.e., diff --git a/man/fmt_number.Rd b/man/fmt_number.Rd index 3958b48c9..4580184d2 100644 --- a/man/fmt_number.Rd +++ b/man/fmt_number.Rd @@ -13,6 +13,7 @@ fmt_number( drop_trailing_zeros = FALSE, drop_trailing_dec_mark = TRUE, use_seps = TRUE, + accounting = FALSE, scale_by = 1, suffixing = FALSE, pattern = "{x}", @@ -61,6 +62,10 @@ which means that trailing decimal marks are not shown.} group separator is set by \code{sep_mark} and overridden if a locale ID is provided to \code{locale}. This setting is \code{TRUE} by default.} +\item{accounting}{An option to use accounting style for values. With \code{FALSE} +(the default), negative values will be shown with a minus sign. Using +\code{accounting = TRUE} will put negative values in parentheses.} + \item{scale_by}{A value to scale the input. The default is \code{1.0}. All numeric values will be multiplied by this value first before undergoing formatting. This value will be ignored if using any of the \code{suffixing} options (i.e., diff --git a/man/fmt_percent.Rd b/man/fmt_percent.Rd index cdb54eae4..6951d8723 100644 --- a/man/fmt_percent.Rd +++ b/man/fmt_percent.Rd @@ -13,6 +13,7 @@ fmt_percent( drop_trailing_dec_mark = TRUE, scale_values = TRUE, use_seps = TRUE, + accounting = FALSE, pattern = "{x}", sep_mark = ",", dec_mark = ".", @@ -59,6 +60,10 @@ already scaled and require only the percent sign when formatted.} group separator is set by \code{sep_mark} and overridden if a locale ID is provided to \code{locale}. This setting is \code{TRUE} by default.} +\item{accounting}{An option to use accounting style for values. With \code{FALSE} +(the default), negative values will be shown with a minus sign. Using +\code{accounting = TRUE} will put negative values in parentheses.} + \item{pattern}{A formatting pattern that allows for decoration of the formatted value. The value itself is represented by \code{{x}} and all other characters are taken to be string literals.} diff --git a/tests/testthat/test-fmt_number.R b/tests/testthat/test-fmt_number.R index 3c4365482..aecfc9879 100644 --- a/tests/testthat/test-fmt_number.R +++ b/tests/testthat/test-fmt_number.R @@ -1,6 +1,4 @@ -context("Ensuring that the `fmt_number()` function works as expected") - -test_that("the `fmt_number()` function works correctly", { +test_that("the `fmt_number()` function works correctly in the HTML context", { # Create an input data frame four columns: two # character-based and two that are numeric @@ -40,167 +38,231 @@ test_that("the `fmt_number()` function works correctly", { # that does not exist expect_error( tab %>% - fmt_number(columns = num_3, decimals = 2)) + fmt_number(columns = num_3, decimals = 2) + ) # Expect an error when using a locale that does not exist expect_error( tab %>% - fmt_number(columns = num_2, decimals = 2, locale = "aa_bb")) + fmt_number(columns = num_2, decimals = 2, locale = "aa_bb") + ) # Format the `num_1` column to 2 decimal places, use all - # other defaults; extract `output_df` and compare to expected values + # other defaults expect_equal( (tab %>% fmt_number(columns = num_1, decimals = 2) %>% render_formats_test(context = "html"))[["num_1"]], - c("1,836.23", "2,763.39", "937.29", "643.00", "212.23", "0.00", "−23.24")) + c("1,836.23", "2,763.39", "937.29", "643.00", "212.23", "0.00", "−23.24") + ) - # Format the `num_1` column to 5 decimal places, use all - # other defaults; extract `output_df` and compare to expected values + # Format the `num_1` column to 5 decimal places, use all other defaults expect_equal( (tab %>% fmt_number(columns = num_1, decimals = 5) %>% render_formats_test("html"))[["num_1"]], - c("1,836.23000", "2,763.39000", "937.29000", "643.00000", - "212.23200", "0.00000", "−23.24000")) + c( + "1,836.23000", "2,763.39000", "937.29000", "643.00000", + "212.23200", "0.00000", "−23.24000" + ) + ) # Format the `num_1` column to 2 decimal places, drop the trailing - # zeros, use all other defaults; extract `output_df` and compare to - # expected values + # zeros, use all other defaults expect_equal( (tab %>% fmt_number(columns = num_1, decimals = 2, drop_trailing_zeros = TRUE) %>% render_formats_test("html"))[["num_1"]], - c("1,836.23", "2,763.39", "937.29", "643", "212.23", "0", "−23.24")) + c("1,836.23", "2,763.39", "937.29", "643", "212.23", "0", "−23.24") + ) # Format the `num_1` column to 2 decimal places, don't use digit - # grouping separators, use all other defaults; extract `output_df` - # and compare to expected values + # grouping separators, use all other defaults expect_equal( (tab %>% fmt_number(columns = num_1, decimals = 2, use_seps = FALSE) %>% render_formats_test("html"))[["num_1"]], - c("1836.23", "2763.39", "937.29", "643.00", "212.23", "0.00", "−23.24")) + c("1836.23", "2763.39", "937.29", "643.00", "212.23", "0.00", "−23.24") + ) # Format the `num_1` column to 2 decimal places, use a single space - # character as digit grouping separators, use all other defaults; - # extract `output_df` and compare to expected values + # character as digit grouping separators, use all other defaults expect_equal( (tab %>% fmt_number(columns = num_1, decimals = 2, sep_mark = " ") %>% render_formats_test("html"))[["num_1"]], - c("1 836.23", "2 763.39", "937.29", "643.00", "212.23", "0.00", "−23.24")) + c("1 836.23", "2 763.39", "937.29", "643.00", "212.23", "0.00", "−23.24") + ) # Format the `num_1` column to 2 decimal places, use a period for the # digit grouping separators and a comma for the decimal mark, use - # all other defaults; extract `output_df` and compare to expected values + # all other defaults expect_equal( (tab %>% fmt_number(columns = num_1, decimals = 2, sep_mark = ".", dec_mark = ",") %>% render_formats_test("html"))[["num_1"]], - c("1.836,23", "2.763,39", "937,29", "643,00", "212,23", "0,00", "−23,24")) + c("1.836,23", "2.763,39", "937,29", "643,00", "212,23", "0,00", "−23,24") + ) # Format the `num_1` column to 4 decimal places, scale all values by - # 1/1000, use all other defaults; extract `output_df` and compare - # to expected values + # 1/1000, use all other defaults expect_equal( (tab %>% fmt_number(columns = num_1, decimals = 4, scale_by = 1/1000) %>% render_formats_test("html"))[["num_1"]], - c("1.8362", "2.7634", "0.9373", "0.6430", "0.2122", "0.0000", "−0.0232")) + c("1.8362", "2.7634", "0.9373", "0.6430", "0.2122", "0.0000", "−0.0232") + ) # Format the `num_1` column to 2 decimal places, prepend and append - # all values by 2 different literals, use all other defaults; extract - # `output_df` and compare to expected values + # all values by 2 different literals, use all other defaults expect_equal( (tab %>% fmt_number(columns = num_1, decimals = 2, pattern = "a {x} b") %>% render_formats_test("html"))[["num_1"]], - c("a 1,836.23 b", "a 2,763.39 b", "a 937.29 b", "a 643.00 b", - "a 212.23 b", "a 0.00 b", "a −23.24 b")) + c( + "a 1,836.23 b", "a 2,763.39 b", "a 937.29 b", "a 643.00 b", + "a 212.23 b", "a 0.00 b", "a −23.24 b" + ) + ) # Format the `num_1` column to 4 decimal places, scale all values # by 1/1000 and append a `K` character to the resultant values, use - # all other defaults; extract `output_df` and compare to expected values + # all other defaults expect_equal( (tab %>% fmt_number(columns = num_1, decimals = 4, scale_by = 1/1000, pattern = "{x}K") %>% render_formats_test("html"))[["num_1"]], - c("1.8362K", "2.7634K", "0.9373K", "0.6430K", - "0.2122K", "0.0000K", "−0.0232K")) + c( + "1.8362K", "2.7634K", "0.9373K", "0.6430K", + "0.2122K", "0.0000K", "−0.0232K" + ) + ) + + # Format the `num_1` column to 2 decimal places, use accounting style + expect_equal( + (tab %>% + fmt_number(columns = num_1, accounting = TRUE) %>% + render_formats_test("html"))[["num_1"]], + c("1,836.23", "2,763.39", "937.29", "643.00", "212.23", "0.00", "(23.24)") + ) + + # Format the `num_1` column to 3 decimal places, use accounting style + expect_equal( + (tab %>% + fmt_number(columns = num_1, decimals = 3, accounting = TRUE) %>% + render_formats_test("html"))[["num_1"]], + c( + "1,836.230", "2,763.390", "937.290", "643.000", "212.232", + "0.000", "(23.240)" + ) + ) + + # Format the `num_1` column to 2 decimal places, use accounting style + # and a pattern around the values + expect_equal( + (tab %>% + fmt_number( + columns = num_1, decimals = 3, + accounting = TRUE, pattern = "a{x}b") %>% + render_formats_test("html"))[["num_1"]], + c( + "a1,836.230b", "a2,763.390b", "a937.290b", "a643.000b", "a212.232b", + "a0.000b", "a(23.240)b" + ) + ) + + # Format the `num_1` column to 2 decimal places, use accounting style + # and drop all trailing zeros + expect_equal( + (tab %>% + fmt_number( + columns = num_1, decimals = 3, + accounting = TRUE, drop_trailing_zeros = TRUE) %>% + render_formats_test("html"))[["num_1"]], + c("1,836.23", "2,763.39", "937.29", "643", "212.232", "0", "(23.24)") + ) # Format the `num_1` column to 2 decimal places, apply the `en_US` - # locale and use all other defaults; extract `output_df` and compare - # to expected values + # locale and use all other defaults expect_equal( (tab %>% fmt_number(columns = num_1, decimals = 2, locale = "en_US") %>% render_formats_test("html"))[["num_1"]], - c("1,836.23", "2,763.39", "937.29", "643.00", "212.23", "0.00", "−23.24")) + c("1,836.23", "2,763.39", "937.29", "643.00", "212.23", "0.00", "−23.24") + ) # Format the `num_1` column to 2 decimal places, apply the `da_DK` - # locale and use all other defaults; extract `output_df` and compare - # to expected values + # locale and use all other defaults expect_equal( (tab %>% fmt_number(columns = num_1, decimals = 2, locale = "da_DK") %>% render_formats_test("html"))[["num_1"]], - c("1.836,23", "2.763,39", "937,29", "643,00", "212,23", "0,00", "−23,24")) + c("1.836,23", "2.763,39", "937,29", "643,00", "212,23", "0,00", "−23,24") + ) # Format the `num_1` column to 2 decimal places, apply the `de_AT` - # locale and use all other defaults; extract `output_df` and compare - # to expected values + # locale and use all other defaults expect_equal( (tab %>% fmt_number(columns = num_1, decimals = 2, locale = "de_AT") %>% render_formats_test("html"))[["num_1"]], - c("1 836,23", "2 763,39", "937,29", "643,00", "212,23", "0,00", "−23,24")) + c("1 836,23", "2 763,39", "937,29", "643,00", "212,23", "0,00", "−23,24") + ) # Format the `num_1` column to 2 decimal places, apply the `et_EE` - # locale and use all other defaults; extract `output_df` and compare - # to expected values + # locale and use all other defaults expect_equal( (tab %>% fmt_number(columns = num_1, decimals = 2, locale = "et_EE") %>% render_formats_test("html"))[["num_1"]], - c("1 836,23", "2 763,39", "937,29", "643,00", "212,23", "0,00", "−23,24")) + c("1 836,23", "2 763,39", "937,29", "643,00", "212,23", "0,00", "−23,24") + ) # Format the `num_1` column to 2 decimal places, apply the `gl_ES` - # locale and use all other defaults; extract `output_df` and compare - # to expected values + # locale and use all other defaults expect_equal( (tab %>% fmt_number(columns = num_1, decimals = 2, locale = "gl_ES") %>% render_formats_test("html"))[["num_1"]], - c("1.836,23", "2.763,39", "937,29", "643,00", "212,23", "0,00", "−23,24")) + c("1.836,23", "2.763,39", "937,29", "643,00", "212,23", "0,00", "−23,24") + ) # Expect that a column with NAs will work fine with `fmt_number()`, # it'll just produce NA values na_col_tbl <- dplyr::tibble(a = rep(NA_real_, 10), b = 1:10) %>% gt() - # Expect a returned object of class `gt_tbl` with various - # uses of `fmt_number()` + # Expect a returned object of class `gt_tbl` with various uses of `fmt_number()` expect_error( - na_col_tbl %>% fmt_number(columns = a) %>% as_raw_html(), NA + regexp = NA, + na_col_tbl %>% fmt_number(columns = a) %>% + as_raw_html() ) expect_error( + regexp = NA, na_col_tbl %>% - fmt_number(columns = a, rows = 1:5) %>% as_raw_html(), NA + fmt_number(columns = a, rows = 1:5) %>% + as_raw_html() ) expect_error( + regexp = NA, na_col_tbl %>% - fmt_number(columns = a, scale_by = 100) %>% as_raw_html(), NA + fmt_number(columns = a, scale_by = 100) %>% + as_raw_html() ) expect_error( + regexp = NA, na_col_tbl %>% - fmt_number(columns = a, suffixing = TRUE) %>% as_raw_html(), NA + fmt_number(columns = a, suffixing = TRUE) %>% + as_raw_html() ) expect_error( + regexp = NA, na_col_tbl %>% - fmt_number(columns = a, pattern = "a{x}b") %>% as_raw_html(), NA + fmt_number(columns = a, pattern = "a{x}b") %>% + as_raw_html() ) # Expect that two columns being formatted (one entirely NA) will work @@ -208,8 +270,7 @@ test_that("the `fmt_number()` function works correctly", { (na_col_tbl %>% fmt_number(columns = a) %>% fmt_number(columns = b) %>% render_formats_test("html"))[["b"]], - c("1.00", "2.00", "3.00", "4.00", "5.00", "6.00", "7.00", "8.00", - "9.00", "10.00") + c("1.00", "2.00", "3.00", "4.00", "5.00", "6.00", "7.00", "8.00", "9.00", "10.00") ) }) @@ -222,66 +283,74 @@ test_that("the `fmt_number()` function can scale/suffix larger numbers", { num = c( -1.8E15, -1.7E13, -1.6E10, -1.5E8, -1.4E6, -1.3E4, -1.2E3, -1.1E1, 0, - 1.1E1, 1.2E3, 1.3E4, 1.4E6, 1.5E8, 1.6E10, 1.7E13, 1.8E15), - stringsAsFactors = FALSE) + 1.1E1, 1.2E3, 1.3E4, 1.4E6, 1.5E8, 1.6E10, 1.7E13, 1.8E15 + ), + stringsAsFactors = FALSE + ) - # Create a `gt_tbl` object with `gt()` and the - # `data_tbl` dataset + # Create a `gt_tbl` object with `gt()` and the `data_tbl` dataset tab <- gt(data = data_tbl) - # Format the `num` column to 2 decimal places, have the - # `suffixing` option set to TRUE (default labels, all - # 4 ranges used) + # Format the `num` column to 2 decimal places, have the `suffixing` option + # set to TRUE (default labels, all 4 ranges used) expect_equal( (tab %>% fmt_number(columns = num, decimals = 2, suffixing = TRUE) %>% render_formats_test(context = "html"))[["num"]], - c("−1,800.00T", "−17.00T", "−16.00B", + c( + "−1,800.00T", "−17.00T", "−16.00B", "−150.00M", "−1.40M", "−13.00K", "−1.20K", "−11.00", "0.00", "11.00", "1.20K", "13.00K", "1.40M", "150.00M", "16.00B", - "17.00T", "1,800.00T") + "17.00T", "1,800.00T" + ) ) - # Format the `num` column to no decimal places, have the - # `suffixing` option set to TRUE (default labels, all - # 4 ranges used) + # Format the `num` column to no decimal places, have the `suffixing` + # option set to TRUE (default labels, all 4 ranges used) expect_equal( (tab %>% fmt_number(columns = num, decimals = 0, suffixing = TRUE) %>% render_formats_test(context = "html"))[["num"]], - c("−1,800T", "−17T", "−16B", "−150M", + c( + "−1,800T", "−17T", "−16B", "−150M", "−1M", "−13K", "−1K", "−11", "0", "11", - "1K", "13K", "1M", "150M", "16B", "17T", "1,800T")) + "1K", "13K", "1M", "150M", "16B", "17T", "1,800T" + ) + ) - # Format the `num` column to 2 decimal places, have the - # `suffixing` option set to use custom symbols across the - # 4 different ranges + # Format the `num` column to 2 decimal places, have the `suffixing` + # option set to use custom symbols across the 4 different ranges expect_equal( (tab %>% fmt_number( columns = num, decimals = 2, suffixing = c("k", "Mn", "Bn", "Tr")) %>% render_formats_test(context = "html"))[["num"]], - c("−1,800.00Tr", "−17.00Tr", "−16.00Bn", + c( + "−1,800.00Tr", "−17.00Tr", "−16.00Bn", "−150.00Mn", "−1.40Mn", "−13.00k", "−1.20k", "−11.00", "0.00", "11.00", "1.20k", - "13.00k", "1.40Mn", "150.00Mn", "16.00Bn", "17.00Tr", "1,800.00Tr")) + "13.00k", "1.40Mn", "150.00Mn", "16.00Bn", "17.00Tr", "1,800.00Tr" + ) + ) - # Format the `num` column to 2 decimal places, have the - # `suffixing` option set to use custom symbols for the middle - # two ranges (millions and billions) + # Format the `num` column to 2 decimal places, have the `suffixing` option + # set to use custom symbols for the middle two ranges (millions and billions) expect_equal( (tab %>% fmt_number( columns = num, decimals = 2, suffixing = c(NA, "Mio.", "Mia.", NA)) %>% render_formats_test(context = "html"))[["num"]], - c("−1,800,000.00Mia.", "−17,000.00Mia.", + c( + "−1,800,000.00Mia.", "−17,000.00Mia.", "−16.00Mia.", "−150.00Mio.", "−1.40Mio.", "−13,000.00", "−1,200.00", "−11.00", "0.00", "11.00", "1,200.00", "13,000.00", "1.40Mio.", "150.00Mio.", "16.00Mia.", - "17,000.00Mia.", "1,800,000.00Mia.")) + "17,000.00Mia.", "1,800,000.00Mia." + ) + ) # Format the `num` column to 2 decimal places, have the # `suffixing` option set to use custom symbols with some NAs @@ -291,29 +360,33 @@ test_that("the `fmt_number()` function can scale/suffix larger numbers", { columns = num, decimals = 2, suffixing = c("K", NA, "Bn", NA, "Qa", NA, NA)) %>% render_formats_test(context = "html"))[["num"]], - c("−1.80Qa", "−17,000.00Bn", "−16.00Bn", + c( + "−1.80Qa", "−17,000.00Bn", "−16.00Bn", "−150,000.00K", "−1,400.00K", "−13.00K", "−1.20K", "−11.00", "0.00", "11.00", "1.20K", "13.00K", - "1,400.00K", "150,000.00K", "16.00Bn", "17,000.00Bn", "1.80Qa")) + "1,400.00K", "150,000.00K", "16.00Bn", "17,000.00Bn", "1.80Qa" + ) + ) - # Format the `num` column to 2 decimal places, have the - # `suffixing` option set to FALSE (the default option, where - # no scaling or suffixing is performed) + # Format the `num` column to 2 decimal places, have the `suffixing` option + # set to FALSE (the default option, where no scaling or suffixing is performed) expect_equal( (tab %>% fmt_number( columns = num, decimals = 2, suffixing = FALSE) %>% render_formats_test(context = "html"))[["num"]], - c("−1,800,000,000,000,000.00", "−17,000,000,000,000.00", + c( + "−1,800,000,000,000,000.00", "−17,000,000,000,000.00", "−16,000,000,000.00", "−150,000,000.00", "−1,400,000.00", "−13,000.00", "−1,200.00", "−11.00", "0.00", "11.00", "1,200.00", "13,000.00", "1,400,000.00", "150,000,000.00", "16,000,000,000.00", - "17,000,000,000,000.00", "1,800,000,000,000,000.00")) + "17,000,000,000,000.00", "1,800,000,000,000,000.00" + ) + ) - # Expect an error if any vector length other than - # four is used for `suffixing` + # Expect an error if any vector length other than four is used for `suffixing` expect_silent( tab %>% fmt_number( @@ -350,7 +423,8 @@ test_that("the `fmt_number()` function can scale/suffix larger numbers", { columns = num, decimals = 1, suffixing = TRUE) %>% render_formats_test(context = "html"))[["num"]], - "1.0K") + "1.0K" + ) expect_equal( (tab_2 %>% @@ -358,7 +432,8 @@ test_that("the `fmt_number()` function can scale/suffix larger numbers", { columns = num, decimals = 2, suffixing = TRUE) %>% render_formats_test(context = "html"))[["num"]], - "1.00K") + "1.00K" + ) expect_equal( (tab_2 %>% @@ -366,7 +441,8 @@ test_that("the `fmt_number()` function can scale/suffix larger numbers", { columns = num, decimals = 3, suffixing = TRUE) %>% render_formats_test(context = "html"))[["num"]], - "1.000K") + "1.000K" + ) expect_equal( (tab_2 %>% @@ -374,7 +450,8 @@ test_that("the `fmt_number()` function can scale/suffix larger numbers", { columns = num, decimals = 4, suffixing = TRUE) %>% render_formats_test(context = "html"))[["num"]], - "999.9999") + "999.9999" + ) expect_equal( (tab_2 %>% @@ -382,7 +459,8 @@ test_that("the `fmt_number()` function can scale/suffix larger numbers", { columns = num, decimals = 5, suffixing = TRUE) %>% render_formats_test(context = "html"))[["num"]], - "999.99990") + "999.99990" + ) }) test_that("the `fmt_number()` function format to specified significant figures", { @@ -414,8 +492,7 @@ test_that("the `fmt_number()` function format to specified significant figures", # Create a single-column tibble with these values in `num` numbers_tbl <- dplyr::tibble(num = numbers) - # Create a `gt_tbl` object with `gt()` and the - # `numbers_tbl` dataset + # Create a `gt_tbl` object with `gt()` and the `numbers_tbl` dataset tab <- gt(data = numbers_tbl) # Format the `num` column to 5 significant figures @@ -423,7 +500,8 @@ test_that("the `fmt_number()` function format to specified significant figures", (tab %>% fmt_number(columns = num, n_sigfig = 5) %>% render_formats_test(context = "html"))[["num"]], - c("50,000", "1,000.0", "10.000", "12,345", "1,234.5", "123.45", + c( + "50,000", "1,000.0", "10.000", "12,345", "1,234.5", "123.45", "1.2345", "0.12345", "0.000012346", "−50,000", "−1,000.0", "−10.000", "−12,345", "−1,234.5", "−123.45", "−1.2345", "−0.12345", "−0.000012346" @@ -435,7 +513,8 @@ test_that("the `fmt_number()` function format to specified significant figures", (tab %>% fmt_number(columns = num, n_sigfig = 4) %>% render_formats_test(context = "html"))[["num"]], - c("50,000", "1,000", "10.00", "12,340", "1,234", "123.4", "1.234", + c( + "50,000", "1,000", "10.00", "12,340", "1,234", "123.4", "1.234", "0.1234", "0.00001235", "−50,000", "−1,000", "−10.00", "−12,340", "−1,234", "−123.4", "−1.234", "−0.1234", "−0.00001235" @@ -447,7 +526,8 @@ test_that("the `fmt_number()` function format to specified significant figures", (tab %>% fmt_number(columns = num, n_sigfig = 3) %>% render_formats_test(context = "html"))[["num"]], - c("50,000", "1,000", "10.0", "12,300", "1,230", "123", "1.23", + c( + "50,000", "1,000", "10.0", "12,300", "1,230", "123", "1.23", "0.123", "0.0000123", "−50,000", "−1,000", "−10.0", "−12,300", "−1,230", "−123", "−1.23", "−0.123", "−0.0000123" @@ -459,7 +539,8 @@ test_that("the `fmt_number()` function format to specified significant figures", (tab %>% fmt_number(columns = num, n_sigfig = 2) %>% render_formats_test(context = "html"))[["num"]], - c("50,000", "1,000", "10", "12,000", "1,200", "120", "1.2", "0.12", + c( + "50,000", "1,000", "10", "12,000", "1,200", "120", "1.2", "0.12", "0.000012", "−50,000", "−1,000", "−10", "−12,000", "−1,200", "−120", "−1.2", "−0.12", "−0.000012" ) @@ -470,7 +551,8 @@ test_that("the `fmt_number()` function format to specified significant figures", (tab %>% fmt_number(columns = num, n_sigfig = 1) %>% render_formats_test(context = "html"))[["num"]], - c("50,000", "1,000", "10", "10,000", "1,000", "100", "1", "0.1", + c( + "50,000", "1,000", "10", "10,000", "1,000", "100", "1", "0.1", "0.00001", "−50,000", "−1,000", "−10", "−10,000", "−1,000", "−100", "−1", "−0.1", "−0.00001" ) @@ -643,44 +725,47 @@ test_that("`fmt_number()` with `suffixing = TRUE` works with small numbers", { num = c( -0.5, -0.05, -0.04, -0.03, -0.02, -0.01, 0, - 0.01, 0.02, 0.03, 0.04, 0.05, 0.5), - stringsAsFactors = FALSE) + 0.01, 0.02, 0.03, 0.04, 0.05, 0.5 + ), + stringsAsFactors = FALSE + ) - # Create a `gt_tbl` object with `gt()` and the - # `data_tbl` dataset + # Create a `gt_tbl` object with `gt()` and the `data_tbl` dataset tab <- gt(data = data_tbl) - # Format the `num` column to 2 decimal places, have the - # `suffixing` option set to TRUE; we shouldn't expect to - # see any suffixes + # Format the `num` column to 2 decimal places, have the `suffixing` option + # set to TRUE; we shouldn't expect to see any suffixes expect_equal( (tab %>% fmt_number(columns = num, decimals = 2, suffixing = TRUE) %>% render_formats_test(context = "html"))[["num"]], - c("−0.50", "−0.05", "−0.04", "−0.03", + c( + "−0.50", "−0.05", "−0.04", "−0.03", "−0.02", "−0.01", "0.00", "0.01", "0.02", "0.03", - "0.04", "0.05", "0.50") + "0.04", "0.05", "0.50" + ) ) }) test_that("rownames and groupnames aren't included in columns = TRUE", { + mtcars1 <- cbind(mtcars, chardata = row.names(mtcars)) # This fails; can't apply numeric formatting to the "chardata" col expect_error(mtcars1 %>% gt() %>% fmt_number(columns = everything())) - - # These succeed; the "chardata" col no longer counts as a resolvable column - # if it's a rowname_col or groupname_col, yet it's still visible as a column - # in the `rows` expression - - expect_error(regexp = NA, + # These succeed because the "chardata" col no longer counts as a + # resolvable column if it's a rowname_col or groupname_col, yet, it's + # still visible as a column in the `rows` expression + expect_error( + regexp = NA, mtcars1 %>% gt(rowname_col = "chardata") %>% fmt_number(columns = everything(), rows = chardata == "Mazda RX4") ) - expect_error(regexp = NA, + expect_error( + regexp = NA, mtcars1 %>% gt(groupname_col = "chardata") %>% fmt_number(columns = everything(), rows = chardata == "Mazda RX4") diff --git a/tests/testthat/test-fmt_percent.R b/tests/testthat/test-fmt_percent.R index 32f65773b..d6181552b 100644 --- a/tests/testthat/test-fmt_percent.R +++ b/tests/testthat/test-fmt_percent.R @@ -1,6 +1,4 @@ -context("Ensuring that the `fmt_percent()` function works as expected") - -test_that("the `fmt_percent()` function works correctly", { +test_that("the `fmt_percent()` function works correctly in the HTML context", { # Create an input data frame four columns: two # character-based and two that are numeric @@ -23,193 +21,261 @@ test_that("the `fmt_percent()` function works correctly", { # that does not exist expect_error( tab %>% - fmt_percent(columns = "num_3", decimals = 2) + fmt_percent(columns = num_3, decimals = 2) ) # Expect an error when using a locale that does not exist expect_error( tab %>% - fmt_percent(columns = "num_2", decimals = 2, locale = "aa_bb") + fmt_percent(columns = num_2, decimals = 2, locale = "aa_bb") ) - # Format the `num_1` column to 2 decimal places, use all - # other defaults; extract `output_df` and compare to expected values + # Format the `num_1` column to 2 decimal places, use all other defaults expect_equal( (tab %>% - fmt_percent(columns = "num_1", decimals = 2) %>% + fmt_percent(columns = num_1, decimals = 2) %>% render_formats_test("html"))[["num_1"]], - c("183,623.00%", "276,339.00%", "93,729.00%", + c( + "183,623.00%", "276,339.00%", "93,729.00%", "64,300.00%", "21,223.20%", "0.00%", - "−2,324.00%") + "−2,324.00%" + ) ) - # Format the `num_1` column to 5 decimal places, use all - # other defaults; extract `output_df` and compare to expected values + # Format the `num_1` column to 5 decimal places, use all other defaults expect_equal( (tab %>% - fmt_percent(columns = "num_1", decimals = 5) %>% + fmt_percent(columns = num_1, decimals = 5) %>% render_formats_test("html"))[["num_1"]], - c("183,623.00000%", "276,339.00000%", "93,729.00000%", + c( + "183,623.00000%", "276,339.00000%", "93,729.00000%", "64,300.00000%", "21,223.20000%", "0.00000%", - "−2,324.00000%") + "−2,324.00000%" + ) ) # Format the `num_1` column to 2 decimal places, drop the trailing - # zeros, use all other defaults; extract `output_df` and compare to - # expected values + # zeros, use all other defaults expect_equal( (tab %>% - fmt_percent(columns = "num_1", decimals = 2, + fmt_percent(columns = num_1, decimals = 2, drop_trailing_zeros = TRUE) %>% render_formats_test("html"))[["num_1"]], - c("183,623%", "276,339%", "93,729%", "64,300%", - "21,223.2%", "0%", "−2,324%") + c( + "183,623%", "276,339%", "93,729%", "64,300%", + "21,223.2%", "0%", "−2,324%" + ) ) # Format the `num_1` column to 2 decimal places, don't use digit - # grouping separators, use all other defaults; extract `output_df` - # and compare to expected values + # grouping separators, use all other defaults expect_equal( (tab %>% - fmt_percent(columns = "num_1", decimals = 2, use_seps = FALSE) %>% + fmt_percent(columns = num_1, decimals = 2, use_seps = FALSE) %>% render_formats_test("html"))[["num_1"]], - c("183623.00%", "276339.00%", "93729.00%", + c( + "183623.00%", "276339.00%", "93729.00%", "64300.00%", "21223.20%", "0.00%", - "−2324.00%") + "−2324.00%" + ) ) # Format the `num_1` column to 2 decimal places, use a single space - # character as digit grouping separators, use all other defaults; - # extract `output_df` and compare to expected values + # character as digit grouping separators, use all other defaults expect_equal( (tab %>% - fmt_percent(columns = "num_1", decimals = 2, sep_mark = " ") %>% + fmt_percent(columns = num_1, decimals = 2, sep_mark = " ") %>% render_formats_test("html"))[["num_1"]], - c("183 623.00%", "276 339.00%", "93 729.00%", + c( + "183 623.00%", "276 339.00%", "93 729.00%", "64 300.00%", "21 223.20%", "0.00%", - "−2 324.00%") + "−2 324.00%" + ) ) # Format the `num_1` column to 2 decimal places, use a period for the # digit grouping separators and a comma for the decimal mark, use - # all other defaults; extract `output_df` and compare to expected values + # all other defaults expect_equal( (tab %>% - fmt_percent(columns = "num_1", decimals = 2, + fmt_percent(columns = num_1, decimals = 2, sep_mark = ".", dec_mark = ",") %>% render_formats_test("html"))[["num_1"]], - c("183.623,00%", "276.339,00%", "93.729,00%", + c( + "183.623,00%", "276.339,00%", "93.729,00%", "64.300,00%", "21.223,20%", "0,00%", - "−2.324,00%") + "−2.324,00%" + ) ) # Format the `num_1` column to 2 decimal places, prepend and append - # all values by 2 different literals, use all other defaults; extract - # `output_df` and compare to expected values + # all values by 2 different literals, use all other defaults expect_equal( (tab %>% - fmt_percent(columns = "num_1", decimals = 2, pattern = "a {x}:n") %>% + fmt_percent(columns = num_1, decimals = 2, pattern = "a {x}:n") %>% render_formats_test("html"))[["num_1"]], - c("a 183,623.00%:n", "a 276,339.00%:n", + c( + "a 183,623.00%:n", "a 276,339.00%:n", "a 93,729.00%:n", "a 64,300.00%:n", "a 21,223.20%:n", "a 0.00%:n", - "a −2,324.00%:n") + "a −2,324.00%:n" + ) ) # Format the `num_1` column to 0 decimal places, place a space between - # the percent sign (on the right) and the value, use all other defaults; - # extract `output_df` and compare to expected values + # the percent sign (on the right) and the value, use all other defaults expect_equal( (tab %>% - fmt_percent(columns = "num_1", decimals = 0, + fmt_percent(columns = num_1, decimals = 0, placement = "right", incl_space = TRUE) %>% render_formats_test("html"))[["num_1"]], - c("183,623 %", "276,339 %", "93,729 %", + c( + "183,623 %", "276,339 %", "93,729 %", "64,300 %", "21,223 %", "0 %", - "−2,324 %") + "−2,324 %" + ) ) # Format the `num_1` column to 0 decimal places, place a space between - # the percent sign (on the left) and the value, use all other defaults; - # extract `output_df` and compare to expected values + # the percent sign (on the left) and the value, use all other defaults expect_equal( (tab %>% - fmt_percent(columns = "num_1", decimals = 0, + fmt_percent(columns = num_1, decimals = 0, placement = "left", incl_space = TRUE) %>% render_formats_test("html"))[["num_1"]], - c("% 183,623", "% 276,339", "% 93,729", + c( + "% 183,623", "% 276,339", "% 93,729", "% 64,300", "% 21,223", "% 0", - "−% 2,324") + "−% 2,324" + ) + ) + + # Format the `num_1` column to 2 decimal places, use accounting style + expect_equal( + (tab %>% + fmt_percent(columns = num_1, accounting = TRUE) %>% + render_formats_test("html"))[["num_1"]], + c( + "183,623.00%", "276,339.00%", "93,729.00%", + "64,300.00%", "21,223.20%", "0.00%", "(2,324.00%)" + ) + ) + + # Format the `num_1` column to 3 decimal places, use accounting style + expect_equal( + (tab %>% + fmt_percent(columns = num_1, decimals = 3, accounting = TRUE) %>% + render_formats_test("html"))[["num_1"]], + c( + "183,623.000%", "276,339.000%", "93,729.000%", + "64,300.000%", "21,223.200%", "0.000%", + "(2,324.000%)" + ) + ) + + # Format the `num_1` column to 2 decimal places, use accounting style + # and a pattern around the values + expect_equal( + (tab %>% + fmt_percent( + columns = num_1, decimals = 3, + accounting = TRUE, pattern = "a{x}b") %>% + render_formats_test("html"))[["num_1"]], + c( + "a183,623.000%b", "a276,339.000%b", "a93,729.000%b", + "a64,300.000%b", "a21,223.200%b", "a0.000%b", + "a(2,324.000%)b" + ) + ) + + # Format the `num_1` column to 2 decimal places, use accounting style + # and drop all trailing zeros + expect_equal( + (tab %>% + fmt_percent( + columns = num_1, decimals = 3, + accounting = TRUE, drop_trailing_zeros = TRUE) %>% + render_formats_test("html"))[["num_1"]], + c( + "183,623%", "276,339%", "93,729%", "64,300%", + "21,223.2%", "0%", "(2,324%)" + ) ) # Format the `num_1` column to 2 decimal places, apply the `en_US` - # locale and use all other defaults; extract `output_df` and compare - # to expected values + # locale and use all other defaults expect_equal( (tab %>% - fmt_percent(columns = "num_1", decimals = 2, locale = "en_US") %>% + fmt_percent(columns = num_1, decimals = 2, locale = "en_US") %>% render_formats_test("html"))[["num_1"]], - c("183,623.00%", "276,339.00%", "93,729.00%", + c( + "183,623.00%", "276,339.00%", "93,729.00%", "64,300.00%", "21,223.20%", "0.00%", - "−2,324.00%") + "−2,324.00%" + ) ) # Format the `num_1` column to 2 decimal places, apply the `da_DK` - # locale and use all other defaults; extract `output_df` and compare - # to expected values + # locale and use all other defaults expect_equal( (tab %>% - fmt_percent(columns = "num_1", decimals = 2, locale = "da_DK") %>% + fmt_percent(columns = num_1, decimals = 2, locale = "da_DK") %>% render_formats_test("html"))[["num_1"]], - c("183.623,00%", "276.339,00%", "93.729,00%", + c( + "183.623,00%", "276.339,00%", "93.729,00%", "64.300,00%", "21.223,20%", "0,00%", - "−2.324,00%") + "−2.324,00%" + ) ) # Format the `num_1` column to 2 decimal places, apply the `de_AT` - # locale and use all other defaults; extract `output_df` and compare - # to expected values + # locale and use all other defaults expect_equal( (tab %>% - fmt_percent(columns = "num_1", decimals = 2, locale = "de_AT") %>% + fmt_percent(columns = num_1, decimals = 2, locale = "de_AT") %>% render_formats_test("html"))[["num_1"]], - c("183 623,00%", "276 339,00%", "93 729,00%", + c( + "183 623,00%", "276 339,00%", "93 729,00%", "64 300,00%", "21 223,20%", "0,00%", - "−2 324,00%") + "−2 324,00%" + ) ) # Format the `num_1` column to 2 decimal places, apply the `et_EE` - # locale and use all other defaults; extract `output_df` and compare - # to expected values + # locale and use all other defaults expect_equal( (tab %>% - fmt_percent(columns = "num_1", decimals = 2, locale = "et_EE") %>% + fmt_percent(columns = num_1, decimals = 2, locale = "et_EE") %>% render_formats_test("html"))[["num_1"]], - c("183 623,00%", "276 339,00%", "93 729,00%", + c( + "183 623,00%", "276 339,00%", "93 729,00%", "64 300,00%", "21 223,20%", "0,00%", - "−2 324,00%") + "−2 324,00%" + ) ) # Format the `num_1` column to 2 decimal places, apply the `gl_ES` - # locale and use all other defaults; extract `output_df` and compare - # to expected values + # locale and use all other defaults expect_equal( (tab %>% - fmt_percent(columns = "num_1", decimals = 2, locale = "gl_ES") %>% + fmt_percent(columns = num_1, decimals = 2, locale = "gl_ES") %>% render_formats_test("html"))[["num_1"]], - c("183.623,00%", "276.339,00%", "93.729,00%", + c( + "183.623,00%", "276.339,00%", "93.729,00%", "64.300,00%", "21.223,20%", "0,00%", - "−2.324,00%") + "−2.324,00%" + ) ) # Format the `num_2` column to 2 decimal places, expect that these - # values are prescaled and just require a percent mark; extract - # `output_df` and compare to expected values + # values are prescaled and just require a percent mark expect_equal( (tab %>% - fmt_percent(columns = "num_2", decimals = 2, scale_values = FALSE) %>% + fmt_percent(columns = num_2, decimals = 2, scale_values = FALSE) %>% render_formats_test("html"))[["num_2"]], - c("34.00%", "74.00%", "23.00%", "93.00%", - "35.00%", "76.00%", "57.00%") + c( + "34.00%", "74.00%", "23.00%", "93.00%", + "35.00%", "76.00%", "57.00%" + ) ) }) diff --git a/tests/testthat/test-l_fmt_number.R b/tests/testthat/test-l_fmt_number.R index cdef2ddc3..807048673 100644 --- a/tests/testthat/test-l_fmt_number.R +++ b/tests/testthat/test-l_fmt_number.R @@ -1,6 +1,4 @@ -context("LaTeX -- Ensuring that the `fmt_number()` function works as expected") - -test_that("the `fmt_number()` function works correctly", { +test_that("the `fmt_number()` function works correctly in the LaTeX context", { # Create an input data frame four columns: two # character-based and two that are numeric @@ -19,162 +17,228 @@ test_that("the `fmt_number()` function works correctly", { # `data_tbl` dataset tbl_latex <- gt(data = data_tbl) - # Format the `num_1` column to 2 decimal places, use all - # other defaults; extract `output_df` and compare to expected values + # Format the `num_1` column to 2 decimal places, use all other defaults expect_equal( (tbl_latex %>% - fmt_number(columns = "num_1", decimals = 2) %>% + fmt_number(columns = num_1, decimals = 2) %>% render_formats_test(context = "latex"))[["num_1"]], - c("$1,836.23$", "$2,763.39$", "$937.29$", "$643.00$", - "$212.23$", "$0.00$", "$-23.24$") + c( + "$1,836.23$", "$2,763.39$", "$937.29$", "$643.00$", + "$212.23$", "$0.00$", "$-23.24$" + ) ) - # Format the `num_1` column to 5 decimal places, use all - # other defaults; extract `output_df` and compare to expected values + # Format the `num_1` column to 5 decimal places, use all other defaults expect_equal( (tbl_latex %>% - fmt_number(columns = "num_1", decimals = 5) %>% + fmt_number(columns = num_1, decimals = 5) %>% render_formats_test("latex"))[["num_1"]], - c("$1,836.23000$", "$2,763.39000$", "$937.29000$", - "$643.00000$", "$212.23200$", "$0.00000$", "$-23.24000$") + c( + "$1,836.23000$", "$2,763.39000$", "$937.29000$", + "$643.00000$", "$212.23200$", "$0.00000$", "$-23.24000$" + ) ) # Format the `num_1` column to 2 decimal places, drop the trailing - # zeros, use all other defaults; extract `output_df` and compare to - # expected values + # zeros, use all other defaults expect_equal( (tbl_latex %>% fmt_number( - columns = "num_1", decimals = 2, + columns = num_1, decimals = 2, drop_trailing_zeros = TRUE ) %>% render_formats_test("latex"))[["num_1"]], - c("$1,836.23$", "$2,763.39$", "$937.29$", "$643$", - "$212.23$", "$0$", "$-23.24$") + c( + "$1,836.23$", "$2,763.39$", "$937.29$", "$643$", + "$212.23$", "$0$", "$-23.24$" + ) ) # Format the `num_1` column to 2 decimal places, don't use digit - # grouping separators, use all other defaults; extract `output_df` - # and compare to expected values + # grouping separators, use all other defaults expect_equal( (tbl_latex %>% - fmt_number(columns = "num_1", decimals = 2, use_seps = FALSE) %>% + fmt_number(columns = num_1, decimals = 2, use_seps = FALSE) %>% render_formats_test("latex"))[["num_1"]], - c("$1836.23$", "$2763.39$", "$937.29$", "$643.00$", - "$212.23$", "$0.00$", "$-23.24$") + c( + "$1836.23$", "$2763.39$", "$937.29$", "$643.00$", + "$212.23$", "$0.00$", "$-23.24$" + ) ) # Format the `num_1` column to 2 decimal places, use a single space - # character as digit grouping separators, use all other defaults; - # extract `output_df` and compare to expected values + # character as digit grouping separators, use all other defaults expect_equal( (tbl_latex %>% - fmt_number(columns = "num_1", decimals = 2, sep_mark = " ") %>% + fmt_number(columns = num_1, decimals = 2, sep_mark = " ") %>% render_formats_test("latex"))[["num_1"]], - c("$1 836.23$", "$2 763.39$", "$937.29$", "$643.00$", - "$212.23$", "$0.00$", "$-23.24$") + c( + "$1 836.23$", "$2 763.39$", "$937.29$", "$643.00$", + "$212.23$", "$0.00$", "$-23.24$" + ) ) # Format the `num_1` column to 2 decimal places, use a period for the # digit grouping separators and a comma for the decimal mark, use - # all other defaults; extract `output_df` and compare to expected values + # all other defaults expect_equal( (tbl_latex %>% fmt_number( - columns = "num_1", decimals = 2, + columns = num_1, decimals = 2, sep_mark = ".", dec_mark = "," ) %>% render_formats_test("latex"))[["num_1"]], - c("$1.836,23$", "$2.763,39$", "$937,29$", "$643,00$", - "$212,23$", "$0,00$", "$-23,24$") + c( + "$1.836,23$", "$2.763,39$", "$937,29$", "$643,00$", + "$212,23$", "$0,00$", "$-23,24$" + ) ) # Format the `num_1` column to 4 decimal places, scale all values by - # 1/1000, use all other defaults; extract `output_df` and compare - # to expected values + # 1/1000, use all other defaults expect_equal( (tbl_latex %>% - fmt_number(columns = "num_1", decimals = 4, scale_by = 1/1000) %>% + fmt_number(columns = num_1, decimals = 4, scale_by = 1/1000) %>% render_formats_test("latex"))[["num_1"]], - c("$1.8362$", "$2.7634$", "$0.9373$", "$0.6430$", "$0.2122$", - "$0.0000$", "$-0.0232$") + c( + "$1.8362$", "$2.7634$", "$0.9373$", "$0.6430$", "$0.2122$", + "$0.0000$", "$-0.0232$" + ) ) # Format the `num_1` column to 2 decimal places, prepend and append - # all values by 2 different literals, use all other defaults; extract - # `output_df` and compare to expected values + # all values by 2 different literals, use all other defaults expect_equal( (tbl_latex %>% - fmt_number(columns = "num_1", decimals = 2, pattern = "a {x} b") %>% + fmt_number(columns = num_1, decimals = 2, pattern = "a {x} b") %>% render_formats_test("latex"))[["num_1"]], - c("a $1,836.23$ b", "a $2,763.39$ b", "a $937.29$ b", "a $643.00$ b", - "a $212.23$ b", "a $0.00$ b", "a $-23.24$ b") + c( + "a $1,836.23$ b", "a $2,763.39$ b", "a $937.29$ b", "a $643.00$ b", + "a $212.23$ b", "a $0.00$ b", "a $-23.24$ b" + ) ) # Format the `num_1` column to 4 decimal places, scale all values # by 1/1000 and append a `K` character to the resultant values, use - # all other defaults; extract `output_df` and compare to expected values + # all other defaults expect_equal( (tbl_latex %>% - fmt_number(columns = "num_1", decimals = 4, + fmt_number(columns = num_1, decimals = 4, scale_by = 1/1000, pattern = "{x}K") %>% render_formats_test("latex"))[["num_1"]], - c("$1.8362$K", "$2.7634$K", "$0.9373$K", "$0.6430$K", - "$0.2122$K", "$0.0000$K", "$-0.0232$K") + c( + "$1.8362$K", "$2.7634$K", "$0.9373$K", "$0.6430$K", + "$0.2122$K", "$0.0000$K", "$-0.0232$K" + ) + ) + + # Format the `num_1` column to 2 decimal places, use accounting style + expect_equal( + (tbl_latex %>% + fmt_number(columns = num_1, accounting = TRUE) %>% + render_formats_test("latex"))[["num_1"]], + c( + "$1,836.23$", "$2,763.39$", "$937.29$", "$643.00$", "$212.23$", + "$0.00$", "$(23.24)$" + ) + ) + + # Format the `num_1` column to 3 decimal places, use accounting style + expect_equal( + (tbl_latex %>% + fmt_number(columns = num_1, decimals = 3, accounting = TRUE) %>% + render_formats_test("latex"))[["num_1"]], + c( + "$1,836.230$", "$2,763.390$", "$937.290$", "$643.000$", "$212.232$", + "$0.000$", "$(23.240)$" + ) + ) + + # Format the `num_1` column to 2 decimal places, use accounting style + # and a pattern around the values + expect_equal( + (tbl_latex %>% + fmt_number( + columns = num_1, decimals = 3, + accounting = TRUE, pattern = "a{x}b") %>% + render_formats_test("latex"))[["num_1"]], + c( + "a$1,836.230$b", "a$2,763.390$b", "a$937.290$b", "a$643.000$b", + "a$212.232$b", "a$0.000$b", "a$(23.240)$b" + ) + ) + + # Format the `num_1` column to 2 decimal places, use accounting style + # and drop all trailing zeros + expect_equal( + (tbl_latex %>% + fmt_number( + columns = num_1, decimals = 3, + accounting = TRUE, drop_trailing_zeros = TRUE) %>% + render_formats_test("latex"))[["num_1"]], + c( + "$1,836.23$", "$2,763.39$", "$937.29$", "$643$", "$212.232$", + "$0$", "$(23.24)$" + ) ) # Format the `num_1` column to 2 decimal places, apply the `en_US` - # locale and use all other defaults; extract `output_df` and compare - # to expected values + # locale and use all other defaults expect_equal( (tbl_latex %>% - fmt_number(columns = "num_1", decimals = 2, locale = "en_US") %>% + fmt_number(columns = num_1, decimals = 2, locale = "en_US") %>% render_formats_test("latex"))[["num_1"]], - c("$1,836.23$", "$2,763.39$", "$937.29$", "$643.00$", - "$212.23$", "$0.00$", "$-23.24$") + c( + "$1,836.23$", "$2,763.39$", "$937.29$", "$643.00$", + "$212.23$", "$0.00$", "$-23.24$" + ) ) # Format the `num_1` column to 2 decimal places, apply the `da_DK` - # locale and use all other defaults; extract `output_df` and compare - # to expected values + # locale and use all other defaults expect_equal( (tbl_latex %>% - fmt_number(columns = "num_1", decimals = 2, locale = "da_DK") %>% + fmt_number(columns = num_1, decimals = 2, locale = "da_DK") %>% render_formats_test("latex"))[["num_1"]], - c("$1.836,23$", "$2.763,39$", "$937,29$", "$643,00$", - "$212,23$", "$0,00$", "$-23,24$") + c( + "$1.836,23$", "$2.763,39$", "$937,29$", "$643,00$", + "$212,23$", "$0,00$", "$-23,24$" + ) ) # Format the `num_1` column to 2 decimal places, apply the `de_AT` - # locale and use all other defaults; extract `output_df` and compare - # to expected values + # locale and use all other defaults expect_equal( (tbl_latex %>% - fmt_number(columns = "num_1", decimals = 2, locale = "de_AT") %>% + fmt_number(columns = num_1, decimals = 2, locale = "de_AT") %>% render_formats_test("latex"))[["num_1"]], - c("$1 836,23$", "$2 763,39$", "$937,29$", "$643,00$", - "$212,23$", "$0,00$", "$-23,24$") + c( + "$1 836,23$", "$2 763,39$", "$937,29$", "$643,00$", + "$212,23$", "$0,00$", "$-23,24$" + ) ) # Format the `num_1` column to 2 decimal places, apply the `et_EE` - # locale and use all other defaults; extract `output_df` and compare - # to expected values + # locale and use all other defaults expect_equal( (tbl_latex %>% - fmt_number(columns = "num_1", decimals = 2, locale = "et_EE") %>% + fmt_number(columns = num_1, decimals = 2, locale = "et_EE") %>% render_formats_test("latex"))[["num_1"]], - c("$1 836,23$", "$2 763,39$", "$937,29$", "$643,00$", - "$212,23$", "$0,00$", "$-23,24$") + c( + "$1 836,23$", "$2 763,39$", "$937,29$", "$643,00$", + "$212,23$", "$0,00$", "$-23,24$" + ) ) # Format the `num_1` column to 2 decimal places, apply the `gl_ES` - # locale and use all other defaults; extract `output_df` and compare - # to expected values + # locale and use all other defaults expect_equal( (tbl_latex %>% - fmt_number(columns = "num_1", decimals = 2, locale = "gl_ES") %>% + fmt_number(columns = num_1, decimals = 2, locale = "gl_ES") %>% render_formats_test("latex"))[["num_1"]], - c("$1.836,23$", "$2.763,39$", "$937,29$", "$643,00$", - "$212,23$", "$0,00$", "$-23,24$") + c( + "$1.836,23$", "$2.763,39$", "$937,29$", "$643,00$", + "$212,23$", "$0,00$", "$-23,24$" + ) ) }) diff --git a/tests/testthat/test-l_fmt_percent.R b/tests/testthat/test-l_fmt_percent.R index 8f841ad68..23258d698 100644 --- a/tests/testthat/test-l_fmt_percent.R +++ b/tests/testthat/test-l_fmt_percent.R @@ -1,6 +1,4 @@ -context("LaTeX -- Ensuring that the `fmt_percent()` function works as expected") - -test_that("the `fmt_percent()` function works correctly", { +test_that("the `fmt_percent()` function works correctly in the LaTeX context", { # Create an input data frame four columns: two # character-based and two that are numeric @@ -23,21 +21,25 @@ test_that("the `fmt_percent()` function works correctly", { # other defaults; extract `output_df` and compare to expected values expect_equal( (tbl_latex %>% - fmt_percent(columns = "num_1", decimals = 2) %>% + fmt_percent(columns = num_1, decimals = 2) %>% render_formats_test("latex"))[["num_1"]], - c("$183,623.00\\%$", "$276,339.00\\%$", "$93,729.00\\%$", - "$64,300.00\\%$", "$21,223.20\\%$", "$0.00\\%$", "$-2,324.00\\%$") + c( + "$183,623.00\\%$", "$276,339.00\\%$", "$93,729.00\\%$", + "$64,300.00\\%$", "$21,223.20\\%$", "$0.00\\%$", "$-2,324.00\\%$" + ) ) # Format the `num_1` column to 5 decimal places, use all # other defaults; extract `output_df` and compare to expected values expect_equal( (tbl_latex %>% - fmt_percent(columns = "num_1", decimals = 5) %>% + fmt_percent(columns = num_1, decimals = 5) %>% render_formats_test("latex"))[["num_1"]], - c("$183,623.00000\\%$", "$276,339.00000\\%$", "$93,729.00000\\%$", + c( + "$183,623.00000\\%$", "$276,339.00000\\%$", "$93,729.00000\\%$", "$64,300.00000\\%$", "$21,223.20000\\%$", "$0.00000\\%$", - "$-2,324.00000\\%$") + "$-2,324.00000\\%$" + ) ) # Format the `num_1` column to 2 decimal places, drop the trailing @@ -46,12 +48,14 @@ test_that("the `fmt_percent()` function works correctly", { expect_equal( (tbl_latex %>% fmt_percent( - columns = "num_1", decimals = 2, + columns = num_1, decimals = 2, drop_trailing_zeros = TRUE ) %>% render_formats_test("latex"))[["num_1"]], - c("$183,623\\%$", "$276,339\\%$", "$93,729\\%$", "$64,300\\%$", - "$21,223.2\\%$", "$0\\%$", "$-2,324\\%$") + c( + "$183,623\\%$", "$276,339\\%$", "$93,729\\%$", "$64,300\\%$", + "$21,223.2\\%$", "$0\\%$", "$-2,324\\%$" + ) ) # Format the `num_1` column to 2 decimal places, don't use digit @@ -59,10 +63,12 @@ test_that("the `fmt_percent()` function works correctly", { # and compare to expected values expect_equal( (tbl_latex %>% - fmt_percent(columns = "num_1", decimals = 2, use_seps = FALSE) %>% + fmt_percent(columns = num_1, decimals = 2, use_seps = FALSE) %>% render_formats_test("latex"))[["num_1"]], - c("$183623.00\\%$", "$276339.00\\%$", "$93729.00\\%$", "$64300.00\\%$", - "$21223.20\\%$", "$0.00\\%$", "$-2324.00\\%$") + c( + "$183623.00\\%$", "$276339.00\\%$", "$93729.00\\%$", "$64300.00\\%$", + "$21223.20\\%$", "$0.00\\%$", "$-2324.00\\%$" + ) ) # Format the `num_1` column to 2 decimal places, use a single space @@ -70,10 +76,12 @@ test_that("the `fmt_percent()` function works correctly", { # extract `output_df` and compare to expected values expect_equal( (tbl_latex %>% - fmt_percent(columns = "num_1", decimals = 2, sep_mark = " ") %>% + fmt_percent(columns = num_1, decimals = 2, sep_mark = " ") %>% render_formats_test("latex"))[["num_1"]], - c("$183 623.00\\%$", "$276 339.00\\%$", "$93 729.00\\%$", "$64 300.00\\%$", - "$21 223.20\\%$", "$0.00\\%$", "$-2 324.00\\%$") + c( + "$183 623.00\\%$", "$276 339.00\\%$", "$93 729.00\\%$", "$64 300.00\\%$", + "$21 223.20\\%$", "$0.00\\%$", "$-2 324.00\\%$" + ) ) # Format the `num_1` column to 2 decimal places, use a period for the @@ -82,12 +90,14 @@ test_that("the `fmt_percent()` function works correctly", { expect_equal( (tbl_latex %>% fmt_percent( - columns = "num_1", decimals = 2, + columns = num_1, decimals = 2, sep_mark = ".", dec_mark = "," ) %>% render_formats_test("latex"))[["num_1"]], - c("$183.623,00\\%$", "$276.339,00\\%$", "$93.729,00\\%$", "$64.300,00\\%$", - "$21.223,20\\%$", "$0,00\\%$", "$-2.324,00\\%$") + c( + "$183.623,00\\%$", "$276.339,00\\%$", "$93.729,00\\%$", "$64.300,00\\%$", + "$21.223,20\\%$", "$0,00\\%$", "$-2.324,00\\%$" + ) ) # Format the `num_1` column to 2 decimal places, prepend and append @@ -95,11 +105,13 @@ test_that("the `fmt_percent()` function works correctly", { # `output_df` and compare to expected values expect_equal( (tbl_latex %>% - fmt_percent(columns = "num_1", decimals = 2, pattern = "a {x}:n") %>% + fmt_percent(columns = num_1, decimals = 2, pattern = "a {x}:n") %>% render_formats_test("latex"))[["num_1"]], - c("a $183,623.00\\%$:n", "a $276,339.00\\%$:n", "a $93,729.00\\%$:n", + c( + "a $183,623.00\\%$:n", "a $276,339.00\\%$:n", "a $93,729.00\\%$:n", "a $64,300.00\\%$:n", "a $21,223.20\\%$:n", "a $0.00\\%$:n", - "a $-2,324.00\\%$:n") + "a $-2,324.00\\%$:n" + ) ) # Format the `num_1` column to 0 decimal places, place a space between @@ -108,12 +120,14 @@ test_that("the `fmt_percent()` function works correctly", { expect_equal( (tbl_latex %>% fmt_percent( - columns = "num_1", decimals = 0, + columns = num_1, decimals = 0, placement = "right", incl_space = TRUE ) %>% render_formats_test("latex"))[["num_1"]], - c("$183,623 \\%$", "$276,339 \\%$", "$93,729 \\%$", "$64,300 \\%$", - "$21,223 \\%$", "$0 \\%$", "$-2,324 \\%$") + c( + "$183,623 \\%$", "$276,339 \\%$", "$93,729 \\%$", "$64,300 \\%$", + "$21,223 \\%$", "$0 \\%$", "$-2,324 \\%$" + ) ) # Format the `num_1` column to 0 decimal places, place a space between @@ -122,12 +136,64 @@ test_that("the `fmt_percent()` function works correctly", { expect_equal( (tbl_latex %>% fmt_percent( - columns = "num_1", decimals = 0, + columns = num_1, decimals = 0, placement = "left", incl_space = TRUE ) %>% render_formats_test("latex"))[["num_1"]], - c("$\\% 183,623$", "$\\% 276,339$", "$\\% 93,729$", "$\\% 64,300$", - "$\\% 21,223$", "$\\% 0$", "$-\\% 2,324$") + c( + "$\\% 183,623$", "$\\% 276,339$", "$\\% 93,729$", "$\\% 64,300$", + "$\\% 21,223$", "$\\% 0$", "$-\\% 2,324$" + ) + ) + + # Format the `num_1` column to 2 decimal places, use accounting style + expect_equal( + (tbl_latex %>% + fmt_percent(columns = num_1, accounting = TRUE) %>% + render_formats_test("latex"))[["num_1"]], + c( + "$183,623.00\\%$", "$276,339.00\\%$", "$93,729.00\\%$", "$64,300.00\\%$", + "$21,223.20\\%$", "$0.00\\%$", "$(2,324.00\\%)$" + ) + ) + + # Format the `num_1` column to 3 decimal places, use accounting style + expect_equal( + (tbl_latex %>% + fmt_percent(columns = num_1, decimals = 3, accounting = TRUE) %>% + render_formats_test("latex"))[["num_1"]], + c( + "$183,623.000\\%$", "$276,339.000\\%$", "$93,729.000\\%$", + "$64,300.000\\%$", "$21,223.200\\%$", "$0.000\\%$", "$(2,324.000\\%)$" + ) + ) + + # Format the `num_1` column to 2 decimal places, use accounting style + # and a pattern around the values + expect_equal( + (tbl_latex %>% + fmt_percent( + columns = num_1, decimals = 3, + accounting = TRUE, pattern = "a{x}b") %>% + render_formats_test("latex"))[["num_1"]], + c( + "a$183,623.000\\%$b", "a$276,339.000\\%$b", "a$93,729.000\\%$b", + "a$64,300.000\\%$b", "a$21,223.200\\%$b", "a$0.000\\%$b", "a$(2,324.000\\%)$b" + ) + ) + + # Format the `num_1` column to 2 decimal places, use accounting style + # and drop all trailing zeros + expect_equal( + (tbl_latex %>% + fmt_percent( + columns = num_1, decimals = 3, + accounting = TRUE, drop_trailing_zeros = TRUE) %>% + render_formats_test("latex"))[["num_1"]], + c( + "$183,623\\%$", "$276,339\\%$", "$93,729\\%$", "$64,300\\%$", + "$21,223.2\\%$", "$0\\%$", "$(2,324\\%)$" + ) ) # Format the `num_1` column to 2 decimal places, apply the `en_US` @@ -135,10 +201,12 @@ test_that("the `fmt_percent()` function works correctly", { # to expected values expect_equal( (tbl_latex %>% - fmt_percent(columns = "num_1", decimals = 2, locale = "en_US") %>% + fmt_percent(columns = num_1, decimals = 2, locale = "en_US") %>% render_formats_test("latex"))[["num_1"]], - c("$183,623.00\\%$", "$276,339.00\\%$", "$93,729.00\\%$", - "$64,300.00\\%$", "$21,223.20\\%$", "$0.00\\%$", "$-2,324.00\\%$") + c( + "$183,623.00\\%$", "$276,339.00\\%$", "$93,729.00\\%$", + "$64,300.00\\%$", "$21,223.20\\%$", "$0.00\\%$", "$-2,324.00\\%$" + ) ) # Format the `num_1` column to 2 decimal places, apply the `da_DK` @@ -146,10 +214,12 @@ test_that("the `fmt_percent()` function works correctly", { # to expected values expect_equal( (tbl_latex %>% - fmt_percent(columns = "num_1", decimals = 2, locale = "da_DK") %>% + fmt_percent(columns = num_1, decimals = 2, locale = "da_DK") %>% render_formats_test("latex"))[["num_1"]], - c("$183.623,00\\%$", "$276.339,00\\%$", "$93.729,00\\%$", - "$64.300,00\\%$", "$21.223,20\\%$", "$0,00\\%$", "$-2.324,00\\%$") + c( + "$183.623,00\\%$", "$276.339,00\\%$", "$93.729,00\\%$", + "$64.300,00\\%$", "$21.223,20\\%$", "$0,00\\%$", "$-2.324,00\\%$" + ) ) # Format the `num_1` column to 2 decimal places, apply the `de_AT` @@ -157,10 +227,12 @@ test_that("the `fmt_percent()` function works correctly", { # to expected values expect_equal( (tbl_latex %>% - fmt_percent(columns = "num_1", decimals = 2, locale = "de_AT") %>% + fmt_percent(columns = num_1, decimals = 2, locale = "de_AT") %>% render_formats_test("latex"))[["num_1"]], - c("$183 623,00\\%$", "$276 339,00\\%$", "$93 729,00\\%$", - "$64 300,00\\%$", "$21 223,20\\%$", "$0,00\\%$", "$-2 324,00\\%$") + c( + "$183 623,00\\%$", "$276 339,00\\%$", "$93 729,00\\%$", + "$64 300,00\\%$", "$21 223,20\\%$", "$0,00\\%$", "$-2 324,00\\%$" + ) ) # Format the `num_1` column to 2 decimal places, apply the `et_EE` @@ -168,10 +240,12 @@ test_that("the `fmt_percent()` function works correctly", { # to expected values expect_equal( (tbl_latex %>% - fmt_percent(columns = "num_1", decimals = 2, locale = "et_EE") %>% + fmt_percent(columns = num_1, decimals = 2, locale = "et_EE") %>% render_formats_test("latex"))[["num_1"]], - c("$183 623,00\\%$", "$276 339,00\\%$", "$93 729,00\\%$", - "$64 300,00\\%$", "$21 223,20\\%$", "$0,00\\%$", "$-2 324,00\\%$") + c( + "$183 623,00\\%$", "$276 339,00\\%$", "$93 729,00\\%$", + "$64 300,00\\%$", "$21 223,20\\%$", "$0,00\\%$", "$-2 324,00\\%$" + ) ) # Format the `num_1` column to 2 decimal places, apply the `gl_ES` @@ -179,9 +253,11 @@ test_that("the `fmt_percent()` function works correctly", { # to expected values expect_equal( (tbl_latex %>% - fmt_percent(columns = "num_1", decimals = 2, locale = "gl_ES") %>% + fmt_percent(columns = num_1, decimals = 2, locale = "gl_ES") %>% render_formats_test("latex"))[["num_1"]], - c("$183.623,00\\%$", "$276.339,00\\%$", "$93.729,00\\%$", - "$64.300,00\\%$", "$21.223,20\\%$", "$0,00\\%$", "$-2.324,00\\%$") + c( + "$183.623,00\\%$", "$276.339,00\\%$", "$93.729,00\\%$", + "$64.300,00\\%$", "$21.223,20\\%$", "$0,00\\%$", "$-2.324,00\\%$" + ) ) }) From dee76b4340772ab054b69d20dc3ef261d2191fa6 Mon Sep 17 00:00:00 2001 From: Richard Iannone Date: Fri, 7 May 2021 16:23:07 -0400 Subject: [PATCH 10/24] Add missing topics to _pkgdown.yml --- _pkgdown.yml | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/_pkgdown.yml b/_pkgdown.yml index 63c276ae3..31563c769 100644 --- a/_pkgdown.yml +++ b/_pkgdown.yml @@ -104,16 +104,15 @@ reference: - title: Helper Functions desc: > - A small assortment of helper functions is available in the **gt** - package. The various `cells_*()` functions are used for targeting - cells with the `locations` argument in the `tab_footnote()`, - `tab_style()`, and `text_transform()` functions. The `cells_styles()` - function is used exclusively with `tab_style()`'s `style` argument - (and the `px()` & `pct()` functions may be useful there for specifying - units in pixels or percentages). The `md()` and `html()` helpers can - used be during label creation with the `tab_header()`, - `tab_footnote()`, `tab_spanner()`, `tab_stubhead_label()`, and - `tab_source_note()` functions. + An assortment of helper functions is available in the **gt** package. + The various `cells_*()` functions are used for targeting cells with the + `locations` argument in the `tab_footnote()`, `tab_style()`, and + `text_transform()` functions. The `cells_styles()` function is used + exclusively with `tab_style()`'s `style` argument (and the `px()` & + `pct()` functions may be useful there for specifying units in pixels or + percentages). The `md()` and `html()` helpers can used be during label + creation with the `tab_header()`, `tab_footnote()`, `tab_spanner()`, + `tab_stubhead_label()`, and `tab_source_note()` functions. contents: - md - html @@ -128,6 +127,10 @@ reference: - cells_body - cells_summary - cells_grand_summary + - cells_stub_summary + - cells_stub_grand_summary + - cells_footnotes + - cells_source_notes - currency - cell_text - cell_fill From f87c667b6cf1bf9aa77d0952603a7a02db4ca443 Mon Sep 17 00:00:00 2001 From: Richard Iannone Date: Tue, 11 May 2021 21:22:10 -0400 Subject: [PATCH 11/24] Documentation fixes (#759) * Reformat help files for `fmt_*()` fns * Update docs for `gt()` and `gt_preview()` * Update docs for `tab_*()` functions * Update help files * Restyle code * Update _pkgdown.yml * Update gt_sp500_table.svg * Update gt_workflow_diagram.svg * Add image to README footer * Delete TODOS.R * Move CoC to .github dir * Update README * Update NEWS.md * Make correction to warning about deprecation * Update NEWS.md * Update NEWS.md * Update resolver.R * Fixing spelling mistake in documentation * Remove inaccurate statement from documentation * Add docs on how locations are created * Update NEWS.md * Update CODE_OF_CONDUCT.md * Update README * Update NEWS.md * Update .Rbuildignore * Update .Rbuildignore * Update NEWS.md --- .Rbuildignore | 7 +- .github/CODE_OF_CONDUCT.md | 133 +++++++++++++++ CODE_OF_CONDUCT.md | 25 --- NEWS.md | 69 +++++++- R/datasets.R | 9 + R/export.R | 6 + R/format_data.R | 245 +++++++++++++++------------- R/gt.R | 2 + R/gt_preview.R | 2 + R/helpers.R | 83 +++++++--- R/info_tables.R | 10 +- R/modify_columns.R | 44 +++-- R/modify_rows.R | 1 + R/opts.R | 22 ++- R/resolver.R | 4 +- R/summary_rows.R | 4 + R/tab_create_modify.R | 50 +++--- R/utils.R | 6 +- README.Rmd | 16 +- README.md | 18 +- TODOS.R | 4 - _pkgdown.yml | 9 +- man/cells_body.Rd | 3 +- man/cells_column_labels.Rd | 3 +- man/cells_column_spanners.Rd | 4 +- man/cells_footnotes.Rd | 8 +- man/cells_grand_summary.Rd | 3 +- man/cells_row_groups.Rd | 5 +- man/cells_source_notes.Rd | 8 +- man/cells_stub.Rd | 7 +- man/cells_stub_grand_summary.Rd | 10 +- man/cells_stub_summary.Rd | 3 +- man/cells_stubhead.Rd | 3 +- man/cells_summary.Rd | 3 +- man/cells_title.Rd | 6 +- man/cols_merge_n_pct.Rd | 1 - man/cols_merge_range.Rd | 1 - man/figures/gt_sp500_table.svg | 15 +- man/figures/gt_tables_footer.png | Bin 0 -> 2414013 bytes man/figures/gt_workflow_diagram.svg | 164 +++++++++---------- man/fmt.Rd | 8 +- man/fmt_bytes.Rd | 9 +- man/fmt_currency.Rd | 4 +- man/fmt_date.Rd | 41 ++--- man/fmt_datetime.Rd | 53 +++--- man/fmt_markdown.Rd | 3 +- man/fmt_missing.Rd | 3 +- man/fmt_number.Rd | 3 +- man/fmt_passthrough.Rd | 3 +- man/fmt_percent.Rd | 3 +- man/fmt_scientific.Rd | 3 +- man/fmt_time.Rd | 19 ++- man/opt_all_caps.Rd | 3 +- man/opt_footnote_marks.Rd | 1 - man/opt_table_font.Rd | 3 +- man/tab_footnote.Rd | 17 +- man/tab_options.Rd | 2 +- 57 files changed, 755 insertions(+), 439 deletions(-) create mode 100644 .github/CODE_OF_CONDUCT.md delete mode 100644 CODE_OF_CONDUCT.md delete mode 100644 TODOS.R create mode 100644 man/figures/gt_tables_footer.png diff --git a/.Rbuildignore b/.Rbuildignore index bba2a0fe0..09a6d70a4 100644 --- a/.Rbuildignore +++ b/.Rbuildignore @@ -5,13 +5,12 @@ ^\.github$ ^\.Rproj\.user$ ^gt\.Rproj$ -^\.travis\.yml$ ^_pkgdown\.yml$ -^appveyor\.yml$ ^codecov\.yml$ ^README\.Rmd$ +^README\.md$ ^LICENSE\.md$ -^CODE_OF_CONDUCT\.md$ -^TODOS tests/gt-examples vignettes +man/figures/.*svg$ +man/figures/[^m].*png$ diff --git a/.github/CODE_OF_CONDUCT.md b/.github/CODE_OF_CONDUCT.md new file mode 100644 index 000000000..e1981cd36 --- /dev/null +++ b/.github/CODE_OF_CONDUCT.md @@ -0,0 +1,133 @@ +# Contributor Covenant Code of Conduct + +## Our Pledge + +We as members, contributors, and leaders pledge to make participation in +our community a harassment-free experience for everyone, regardless of +age, body size, visible or invisible disability, ethnicity, sex +characteristics, gender identity and expression, level of experience, +education, socio-economic status, nationality, personal appearance, +race, religion, or sexual identity and orientation. + +We pledge to act and interact in ways that contribute to an open, +welcoming, diverse, inclusive, and healthy community. + +## Our Standards + +Examples of behavior that contributes to a positive environment for our +community include: + +* Demonstrating empathy and kindness toward other people +* Being respectful of differing opinions, viewpoints, and experiences +* Giving and gracefully accepting constructive feedback +* Accepting responsibility and apologizing to those affected by our + mistakes, and learning from the experience +* Focusing on what is best not just for us as individuals, but for the + overall community + +Examples of unacceptable behavior include: + +* The use of sexualized language or imagery, and sexual attention or + advances of any kind +* Trolling, insulting or derogatory comments, and personal or political + attacks +* Public or private harassment +* Publishing others' private information, such as a physical or email + address, without their explicit permission +* Other conduct which could reasonably be considered inappropriate in a + professional setting + +## Enforcement Responsibilities + +Community leaders are responsible for clarifying and enforcing our +standards of acceptable behavior and will take appropriate and fair +corrective action in response to any behavior that they deem +inappropriate, threatening, offensive, or harmful. + +Community leaders have the right and responsibility to remove, edit, or +reject comments, commits, code, wiki edits, issues, and other +contributions that are not aligned to this Code of Conduct, and will +communicate reasons for moderation decisions when appropriate. + +## Scope + +This Code of Conduct applies within all community spaces, and also +applies when an individual is officially representing the community in +public spaces. Examples of representing our community include using an +official e-mail address, posting via an official social media account, +or acting as an appointed representative at an online or offline event. + +## Enforcement + +Instances of abusive, harassing, or otherwise unacceptable behavior may +be reported to the community leaders responsible for enforcement at +[rich@rstudio.com](mailto:rich@rstudio.com). All +complaints will be reviewed and investigated promptly and fairly. + +All community leaders are obligated to respect the privacy and security +of the reporter of any incident. + +## Enforcement Guidelines + +Community leaders will follow these Community Impact Guidelines in +determining the consequences for any action they deem in violation of +this Code of Conduct: + +### 1. Correction + +**Community Impact**: Use of inappropriate language or other behavior +deemed unprofessional or unwelcome in the community. + +**Consequence**: A private, written warning from community leaders, +providing clarity around the nature of the violation and an explanation +of why the behavior was inappropriate. A public apology may be +requested. + +### 2. Warning + +**Community Impact**: A violation through a single incident or series of +actions. + +**Consequence**: A warning with consequences for continued behavior. No +interaction with the people involved, including unsolicited interaction +with those enforcing the Code of Conduct, for a specified period of +time. This includes avoiding interactions in community spaces as well as +external channels like social media. Violating these terms may lead to a +temporary or permanent ban. + +### 3. Temporary Ban + +**Community Impact**: A serious violation of community standards, +including sustained inappropriate behavior. + +**Consequence**: A temporary ban from any sort of interaction or public +communication with the community for a specified period of time. No +public or private interaction with the people involved, including +unsolicited interaction with those enforcing the Code of Conduct, is +allowed during this period. Violating these terms may lead to a +permanent ban. + +### 4. Permanent Ban + +**Community Impact**: Demonstrating a pattern of violation of community +standards, including sustained inappropriate behavior, harassment of an +individual, or aggression toward or disparagement of classes of +individuals. + +**Consequence**: A permanent ban from any sort of public interaction +within the community. + +## Attribution + +This Code of Conduct is adapted from the +[Contributor Covenant][homepage], version 2.0, available at +https://www.contributor-covenant.org/version/2/0/code_of_conduct.html. + +Community Impact Guidelines were inspired by +[Mozilla's code of conduct enforcement ladder](https://github.com/mozilla/diversity). + +[homepage]: https://www.contributor-covenant.org + +For answers to common questions about this code of conduct, see the FAQ +at https://www.contributor-covenant.org/faq. Translations are available +at https://www.contributor-covenant.org/translations. diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md deleted file mode 100644 index 24aa0a3cd..000000000 --- a/CODE_OF_CONDUCT.md +++ /dev/null @@ -1,25 +0,0 @@ -# Contributor Code of Conduct - -As contributors and maintainers of this project, we pledge to respect all people who -contribute through reporting issues, posting feature requests, updating documentation, -submitting pull requests or patches, and other activities. - -We are committed to making participation in this project a harassment-free experience for -everyone, regardless of level of experience, gender, gender identity and expression, -sexual orientation, disability, personal appearance, body size, race, ethnicity, age, or religion. - -Examples of unacceptable behavior by participants include the use of sexual language or -imagery, derogatory comments or personal attacks, trolling, public or private harassment, -insults, or other unprofessional conduct. - -Project maintainers have the right and responsibility to remove, edit, or reject comments, -commits, code, wiki edits, issues, and other contributions that are not aligned to this -Code of Conduct. Project maintainers who do not follow the Code of Conduct may be removed -from the project team. - -Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by -opening an issue or contacting one or more of the project maintainers. - -This Code of Conduct is adapted from the Contributor Covenant -(http://contributor-covenant.org), version 1.0.0, available at -http://contributor-covenant.org/version/1/0/0/ diff --git a/NEWS.md b/NEWS.md index de24c5d67..195097070 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,3 +1,68 @@ +# gt (development version) + +This release focuses on improvements to two main areas: + +1. Better RTF output support: + * RTF table generation is now fit for use following an extensive rewrite of internal RTF rendering functions. + * RTF table output with `gtsave(..., ".rtf")` and `as_rtf()` now has much more feature parity compared to HTML tables; we can now add summary rows, format table text with Markdown via `fmt_markdown()`, and expect tables that look acceptable in Word and text editors that are RTF-compatible. + +2. Implementation of **tidyselect** semantics: + * References to columns (by way of the `columns` argument in many **gt** functions) now better adhere to **tidyselect** semantics. + * Instead of using `columns = vars(a, b)`, we now use `columns = c(a, b)` (`columns = c("a", "b")` also works, and this type of expression always has been an option in **gt**). + * Other **tidyselect** idioms should also work; things like using `where()` to target columns (e.g., `gt(exibble) %>% cols_hide(columns = where(is.numeric))` will hide all numeric columns) and negation (e.g., `columns = -c(a, b)`) function as expected. + +## Breaking changes and deprecations + +* Column labels subordinate to column spanner labels had their alignment forced to be `"center"` but now there is no specialized alignment of column labels under spanners. Should you need the old behavior, `tab_style()` can be used along with `cell_text(align = "center")` for all columns that live under spanners. (#662) + +* The automatic alignment of integer values has been changed from `"center"` to `"right"`. To correct for this, use `tab_style()` with `cell_text(align = "center")` for all affected columns. (#662) + +* As part of the **tidyselect** changes made in this release, using `columns = TRUE` (to mean that all columns should be considered) has now been replaced with `columns = everything()`. Using the former will result in a warning message. (#718) + +* While `vars()` is still reexported in **gt**, its use with the `columns` argument (present in a large number of functions) is deprecated and a warning message will appear if it is used. In a later release, it can be expected that `vars()` will no longer be reexported. (#718) + +* The `others_label` argument of `tab_row_group()` is deprecated since it was confusing to use. To specify a default label for row groups, the course of action is now to use `tab_options(row_group.default_label =