From a43e916de0814eab57c28c578ccce9369cd552f9 Mon Sep 17 00:00:00 2001 From: iaugusty Date: Thu, 27 Nov 2025 13:23:19 +0000 Subject: [PATCH 01/18] - add new round_type method (iec_mod) + modify behaviour of sas rounding in certain situation - introduce getter and setter for round_type --- R/format_value.R | 42 ++++++++++++++++++++++++++++++++++-------- R/generics.R | 26 ++++++++++++++++++++++---- R/matrix_form.R | 7 +++++-- R/mpf_exporters.R | 15 +++++++++++---- R/pagination.R | 12 ++++++++---- R/tostring.R | 7 +++++-- 6 files changed, 85 insertions(+), 24 deletions(-) diff --git a/R/format_value.R b/R/format_value.R index 0dde671ab..8df6e679e 100644 --- a/R/format_value.R +++ b/R/format_value.R @@ -157,6 +157,9 @@ sprintf_format <- function(format) { } } +#' @export +valid_round_type <- c("iec", "iec_mod", "sas") + #' Round and prepare a value for display #' #' This function is used within [format_value()] to prepare numeric values within @@ -166,9 +169,12 @@ sprintf_format <- function(format) { #' @param digits (`numeric(1)`)\cr number of digits to round to, or `NA` to convert to a #' character value with no rounding. #' @param na_str (`string`)\cr the value to return if `x` is `NA`. -#' @param round_type (`"iec"` or `"sas"`)\cr the type of rounding to perform. iec, -#' the default, peforms rounding compliant with IEC 60559 (see details), while -#' sas performs nearest-value rounding consistent with rounding within SAS. +#' @param round_type (`"iec"`, `"iec_mod"` or `"sas"`)\cr the type of rounding to perform. iec, +#' the default, and iec_mod peforms rounding compliant with IEC 60559 (see notes in [round_fmt()]), while +#' sas performs nearest-value rounding consistent with rounding within SAS.\cr +#' In addition, the rounding of a negative number that rounds to zero will be presented as 0 +#' (with the appropriate number of trailing zeros) for both `sas` and `iec_mod`, +#' while for `iec`, it will be presented as -0 (with the appropriate number of trailing zeros). #' #' @details #' This function combines rounding behavior with the strict decimal display of @@ -207,10 +213,13 @@ sprintf_format <- function(format) { #' round_fmt(2.765923, digits = NA) #' round_fmt(0.845, digits = 2) #' round_fmt(0.845, digits = 2, round_type = "sas") +#' round_fmt(-0.001, digits = 2, round_type = "iec") +#' round_fmt(-0.001, digits = 2, round_type = "sas") +#' round_fmt(-0.001, digits = 2, round_type = "iec_mod") #' #' @export #' @aliases rounding -round_fmt <- function(x, digits, na_str = "NA", round_type = c("iec", "sas")) { +round_fmt <- function(x, digits, na_str = "NA", round_type = valid_round_type) { round_type <- match.arg(round_type) if (!is.na(digits) && digits < 0) { stop("round_fmt currently does not support non-missing values of digits < 0") @@ -222,6 +231,7 @@ round_fmt <- function(x, digits, na_str = "NA", round_type = c("iec", "sas")) { } else { rndx <- switch(round_type, iec = round(x, digits), + iec_mod = round_iec_mod(x, digits), sas = round_sas(x, digits) ) sprfmt <- paste0("%.", digits, "f") @@ -241,13 +251,28 @@ round_sas <- function(x, z <- z + 0.5 + sqrt(.Machine$double.eps) z <- trunc(z) z <- z / 10^digits - z <- z * posneg + # only include sign when rounded value is not zero + if (z != 0) z <- z * posneg + ## return numeric vector of rounded values + z +} + +#' @inheritParams round_fmt +#' +round_iec_mod <- function(x, + digits = 0) { + # perform default rounding ---------------------------------------------------- + posneg <- sign(x) + z <- round(abs(x), digits) + # only include sign when rounded value is not zero + if (z != 0) z <- z * posneg ## return numeric vector of rounded values z } -val_pct_helper <- function(x, dig1, dig2, na_str, pct = TRUE, round_type = c("iec", "sas")) { +val_pct_helper <- function(x, dig1, dig2, na_str, pct = TRUE, round_type = valid_round_type) { + round_type <- match.arg(round_type) if (pct) { x[2] <- x[2] * 100 } @@ -262,7 +287,8 @@ val_pct_helper <- function(x, dig1, dig2, na_str, pct = TRUE, round_type = c("ie ) } -sep_2d_helper <- function(x, dig1, dig2, sep, na_str, wrap = NULL, round_type = c("iec", "sas")) { +sep_2d_helper <- function(x, dig1, dig2, sep, na_str, wrap = NULL, round_type = valid_round_type) { + round_type <- match.arg(round_type) ret <- paste(mapply(round_fmt, x = x, digits = c(dig1, dig2), na_str = na_str, round_type = round_type), collapse = sep ) @@ -305,7 +331,7 @@ sep_2d_helper <- function(x, dig1, dig2, sep, na_str, wrap = NULL, round_type = #' format_value(c(NA, 1, NA), format = "xx.x (xx.x - xx.x)", na_str = c("NE", "")) #' #' @export -format_value <- function(x, format = NULL, output = c("ascii", "html"), na_str = "NA", round_type = c("iec", "sas")) { +format_value <- function(x, format = NULL, output = c("ascii", "html"), na_str = "NA", round_type = valid_round_type) { ## if(is(x, "CellValue")) ## x = x[[1]] diff --git a/R/generics.R b/R/generics.R index fb5e46dfd..7d4fe2fbd 100644 --- a/R/generics.R +++ b/R/generics.R @@ -68,7 +68,8 @@ setGeneric("make_row_df", function(tt, colwidths = NULL, visible_only = TRUE, max_width = NULL, fontspec = font_spec(), col_gap = 3L, - round_type = c("iec", "sas")) { + round_type = valid_round_type) { + round_type <- match.arg(round_type) standardGeneric("make_row_df") }) @@ -85,7 +86,7 @@ setMethod("make_row_df", "MatrixPrintForm", function(tt, colwidths = NULL, visib max_width = NULL, fontspec = font_spec(), col_gap = mf_colgap(tt) %||% 3L, - round_type = c("iec", "sas")) { + round_type = valid_round_type) { msg <- paste0( "make_row_df can be used only on {rtables} table objects, and not on `matrix_form`-", "generated objects (MatrixPrintForm)." @@ -127,7 +128,7 @@ setGeneric("matrix_form", function(obj, indent_size = 2, fontspec = NULL, col_gap = NULL, - round_type = c("iec", "sas")) { + round_type = valid_round_type) { standardGeneric("matrix_form") }) @@ -140,7 +141,7 @@ setMethod("matrix_form", "MatrixPrintForm", function(obj, indent_size = 2, fontspec = NULL, col_gap = NULL, - round_type = c("iec", "sas")) { + round_type = valid_round_type) { if (!is.null(fontspec)) { mf_fontspec(obj) <- fontspec } @@ -737,3 +738,20 @@ setMethod( obj } ) + + +# obj_round_type --------------------------------------------------------------- +#' @export +setGeneric("obj_round_type", function(obj) standardGeneric("obj_round_type")) + +#' @export +setMethod( + "obj_round_type", "MatrixPrintForm", function(obj) obj@round_type +) + +# obj_round_type setter --------------------------------------------------------------- +#' @export +setGeneric("obj_round_type<-", function(obj, value) standardGeneric("obj_round_type<-")) + + + diff --git a/R/matrix_form.R b/R/matrix_form.R index 3310c4a52..d1009391e 100644 --- a/R/matrix_form.R +++ b/R/matrix_form.R @@ -325,7 +325,9 @@ MatrixPrintForm <- function(strings = NULL, colwidths = NULL, indent_size = 2, fontspec = font_spec(), - rep_cols = 0L) { + rep_cols = 0L, + round_type = valid_round_type) { + round_type <- match.arg(round_type) display <- disp_from_spans(spans) ncs <- if (has_rowlabs) ncol(strings) - 1 else ncol(strings) @@ -353,7 +355,8 @@ MatrixPrintForm <- function(strings = NULL, indent_size = indent_size, col_widths = colwidths, fontspec = fontspec, - num_rep_cols = rep_cols + num_rep_cols = rep_cols, + round_type = round_type ), nrow_header = nrow_header, ncols = ncs, diff --git a/R/mpf_exporters.R b/R/mpf_exporters.R index 56d3753b9..0864dab74 100644 --- a/R/mpf_exporters.R +++ b/R/mpf_exporters.R @@ -60,7 +60,8 @@ export_as_txt <- function(x, page_num = default_page_number(), fontspec = font_spec(font_family, font_size, lineheight), col_gap = 3, - round_type = c("iec", "sas")) { + round_type = valid_round_type) { + round_type <- match.arg(round_type) # Processing lists of tables or listings if (.is_list_of_tables_or_listings(x)) { if (isFALSE(paginate)) { @@ -186,7 +187,8 @@ prep_header_line <- function(mf, i) { ## ) ## } -mpf_to_dfbody <- function(mpf, colwidths, fontspec, round_type = c("iec", "sas")) { +mpf_to_dfbody <- function(mpf, colwidths, fontspec, round_type = valid_round_type) { + round_type <- match.arg(round_type) mf <- matrix_form(mpf, indent_rownames = TRUE, fontspec = fontspec, round_type = round_type) nlr <- mf_nlheader(mf) if (is.null(colwidths)) { @@ -420,7 +422,9 @@ export_as_rtf <- function(x, lineheight = 1, fontspec = font_spec(font_family, font_size, lineheight), paginate = TRUE, + round_type = valid_round_type, ...) { + round_type <- match.arg(round_type) # Processing lists of tables or listings if (.is_list_of_tables_or_listings(x)) { if (isFALSE(paginate)) { @@ -464,6 +468,7 @@ export_as_rtf <- function(x, margins = c(bottom = 0, left = 0, top = 0, right = 0), lineheight = 1.25, colwidths = colwidths, + round_type = round_type, ... ) @@ -474,7 +479,8 @@ export_as_rtf <- function(x, pg_width = pg_width, pg_height = pg_height, font_size = fontspec$size, - margins = c(top = 0, left = 0, bottom = 0, right = 0) + margins = c(top = 0, left = 0, bottom = 0, right = 0), + round_type = round_type )) }) restxt <- paste( @@ -563,7 +569,8 @@ export_as_pdf <- function(x, colwidths = NULL, fontspec = font_spec(font_family, font_size, lineheight), ttype_ok = FALSE, - round_type = c("iec", "sas")) { + round_type = valid_round_type) { + round_type <- match.arg(round_type) ## this has to happen at the very beginning before the first use of fontspec ## which happens in the default value of colwidths. yay lazy evaluation... if (missing(font_size) && !missing(fontsize)) { diff --git a/R/pagination.R b/R/pagination.R index acdc103a5..499108c76 100644 --- a/R/pagination.R +++ b/R/pagination.R @@ -590,7 +590,8 @@ vert_pag_indices <- function(mf, rep_cols = 0L, fontspec, nosplitin = character(), - round_type = c("iec", "sas")) { + round_type = valid_round_type) { + round_type <- match.arg(round_type) if (is.list(nosplitin)) { nosplitin <- nosplitin[["cols"]] } @@ -1001,8 +1002,9 @@ paginate_indices <- function(obj, rep_cols = num_rep_cols(obj), col_gap = 3, fontspec = font_spec(font_family, font_size, lineheight), - round_type = c("iec", "sas"), + round_type = valid_round_type, verbose = FALSE) { + round_type <- match.arg(round_type) ## this preserves backwards compatibility ## could start deprecation cycle of char input if (is.character(nosplitin)) { @@ -1202,8 +1204,9 @@ paginate_to_mpfs <- function(obj, # col_gap = 3, # this could be change in default - breaking change col_gap = 3, fontspec = font_spec(font_family, font_size, lineheight), - round_type = c("iec", "sas"), + round_type = valid_round_type, verbose = FALSE) { + round_type <- match.arg(round_type) newdev <- open_font_dev(fontspec) if (newdev) { on.exit(close_font_dev()) @@ -1503,8 +1506,9 @@ diagnose_pagination <- function(obj, font_size, lineheight ), - round_type = c("iec", "sas"), + round_type = valid_round_type, ...) { + round_type <- match.arg(round_type) new_dev <- open_font_dev(fontspec) if (new_dev) { on.exit(close_font_dev()) diff --git a/R/tostring.R b/R/tostring.R index f471bcc83..c4d280fab 100644 --- a/R/tostring.R +++ b/R/tostring.R @@ -646,8 +646,9 @@ setMethod("toString", "MatrixPrintForm", function(x, hsep = NULL, fontspec = font_spec(), ttype_ok = FALSE, - round_type = c("iec", "sas")) { + round_type = valid_round_type) { checkmate::assert_flag(tf_wrap) + round_type <- match.arg(round_type) ## we are going to use the pdf device and grid to understand the actual ## print width of things given our font family and font size @@ -1379,7 +1380,9 @@ spans_to_viscell <- function(spans) { propose_column_widths <- function(x, indent_size = 2, fontspec = font_spec(), - round_type = c("iec", "sas")) { + round_type = valid_round_type) { + round_type <- match.arg(round_type) + new_dev <- open_font_dev(fontspec) if (new_dev) { on.exit(close_font_dev()) From 701c5081d3d031952b6e9609e287616c5f095b02 Mon Sep 17 00:00:00 2001 From: iaugusty Date: Thu, 27 Nov 2025 13:24:10 +0000 Subject: [PATCH 02/18] add some tests for modified rounding behaviour --- tests/testthat/test-formatters.R | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/tests/testthat/test-formatters.R b/tests/testthat/test-formatters.R index 76b7d8764..43d64f0c5 100644 --- a/tests/testthat/test-formatters.R +++ b/tests/testthat/test-formatters.R @@ -1016,6 +1016,23 @@ test_that("sas-style rounding works", { "7.85" ) + expect_identical( + format_value(-0.001, "xx.xx", round_type = "iec"), + "-0.00" + ) + + expect_identical( + format_value(-0.001, "xx.xx", round_type = "sas"), + "0.00" + ) + + expect_identical( + format_value(-0.001, "xx.xx", round_type = "iec_mod"), + "0.00" + ) + + + forms <- list_valid_format_labels() for (fmtset in 1:3) { for (digs in 0:3) { From 8fa1439be92f0c68d95feaa145a2fdb304a7f5bb Mon Sep 17 00:00:00 2001 From: iaugusty Date: Thu, 27 Nov 2025 13:24:49 +0000 Subject: [PATCH 03/18] document --- NAMESPACE | 4 ++++ man/MatrixPrintForm.Rd | 3 ++- man/export_as_pdf.Rd | 11 +++++++---- man/export_as_rtf.Rd | 8 ++++++++ man/export_as_txt.Rd | 11 +++++++---- man/format_value.Rd | 11 +++++++---- man/make_row_df.Rd | 13 ++++++++----- man/matrix_form.Rd | 13 ++++++++----- man/mpf_to_rtf.Rd | 9 ++++++--- man/paginate_indices.Rd | 15 +++++++++------ man/propose_column_widths.Rd | 11 +++++++---- man/round_fmt.Rd | 14 ++++++++++---- man/tostring.Rd | 11 +++++++---- man/vert_pag_indices.Rd | 11 +++++++---- 14 files changed, 97 insertions(+), 48 deletions(-) diff --git a/NAMESPACE b/NAMESPACE index 93dc9004e..35f84dc5b 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -22,6 +22,7 @@ export("obj_format<-") export("obj_label<-") export("obj_na_str<-") export("obj_name<-") +export("obj_round_type<-") export("page_titles<-") export("prov_footer<-") export("subtitles<-") @@ -83,6 +84,7 @@ export(obj_format) export(obj_label) export(obj_na_str) export(obj_name) +export(obj_round_type) export(open_font_dev) export(padstr) export(pag_indices_inner) @@ -107,6 +109,7 @@ export(subtitles) export(table_inset) export(toString) export(undebug_font_dev) +export(valid_round_type) export(var_labels) export(var_labels_remove) export(var_relabel) @@ -139,6 +142,7 @@ exportMethods(obj_align) exportMethods(obj_format) exportMethods(obj_label) exportMethods(obj_na_str) +exportMethods(obj_round_type) exportMethods(page_titles) exportMethods(prov_footer) exportMethods(subtitles) diff --git a/man/MatrixPrintForm.Rd b/man/MatrixPrintForm.Rd index 67a9c9631..f34db80e1 100644 --- a/man/MatrixPrintForm.Rd +++ b/man/MatrixPrintForm.Rd @@ -31,7 +31,8 @@ MatrixPrintForm( colwidths = NULL, indent_size = 2, fontspec = font_spec(), - rep_cols = 0L + rep_cols = 0L, + round_type = valid_round_type ) } \arguments{ diff --git a/man/export_as_pdf.Rd b/man/export_as_pdf.Rd index 26ae91643..7581e735f 100644 --- a/man/export_as_pdf.Rd +++ b/man/export_as_pdf.Rd @@ -31,7 +31,7 @@ export_as_pdf( colwidths = NULL, fontspec = font_spec(font_family, font_size, lineheight), ttype_ok = FALSE, - round_type = c("iec", "sas") + round_type = valid_round_type ) } \arguments{ @@ -109,9 +109,12 @@ calculating string widths and heights, as returned by \code{\link[=font_spec]{fo allowed via \code{fontspec}. Defaults to \code{FALSE}. This parameter is primarily for internal testing and generally should not be set by end users.} -\item{round_type}{(\code{"iec"} or \code{"sas"})\cr the type of rounding to perform. iec, -the default, peforms rounding compliant with IEC 60559 (see details), while -sas performs nearest-value rounding consistent with rounding within SAS.} +\item{round_type}{(\code{"iec"}, \code{"iec_mod"} or \code{"sas"})\cr the type of rounding to perform. iec, +the default, and iec_mod peforms rounding compliant with IEC 60559 (see notes in \code{\link[=round_fmt]{round_fmt()}}), while +sas performs nearest-value rounding consistent with rounding within SAS.\cr +In addition, the rounding of a negative number that rounds to zero will be presented as 0 +(with the appropriate number of trailing zeros) for both \code{sas} and \code{iec_mod}, +while for \code{iec}, it will be presented as -0 (with the appropriate number of trailing zeros).} } \description{ The PDF output from this function is based on the ASCII output created with \code{\link[=toString]{toString()}}. diff --git a/man/export_as_rtf.Rd b/man/export_as_rtf.Rd index 689c35271..b6a8ca3b9 100644 --- a/man/export_as_rtf.Rd +++ b/man/export_as_rtf.Rd @@ -18,6 +18,7 @@ export_as_rtf( lineheight = 1, fontspec = font_spec(font_family, font_size, lineheight), paginate = TRUE, + round_type = valid_round_type, ... ) } @@ -57,6 +58,13 @@ calculating string widths and heights, as returned by \code{\link[=font_spec]{fo \item{paginate}{(\code{flag})\cr whether pagination should be performed. Defaults to \code{TRUE} if page size is specified (including the default).} +\item{round_type}{(\code{"iec"}, \code{"iec_mod"} or \code{"sas"})\cr the type of rounding to perform. iec, +the default, and iec_mod peforms rounding compliant with IEC 60559 (see notes in \code{\link[=round_fmt]{round_fmt()}}), while +sas performs nearest-value rounding consistent with rounding within SAS.\cr +In addition, the rounding of a negative number that rounds to zero will be presented as 0 +(with the appropriate number of trailing zeros) for both \code{sas} and \code{iec_mod}, +while for \code{iec}, it will be presented as -0 (with the appropriate number of trailing zeros).} + \item{...}{additional parameters passed to \code{\link[=paginate_to_mpfs]{paginate_to_mpfs()}}.} } \description{ diff --git a/man/export_as_txt.Rd b/man/export_as_txt.Rd index d566cc936..d63685d9e 100644 --- a/man/export_as_txt.Rd +++ b/man/export_as_txt.Rd @@ -32,7 +32,7 @@ export_as_txt( page_num = default_page_number(), fontspec = font_spec(font_family, font_size, lineheight), col_gap = 3, - round_type = c("iec", "sas") + round_type = valid_round_type ) } \arguments{ @@ -113,9 +113,12 @@ calculating string widths and heights, as returned by \code{\link[=font_spec]{fo \item{col_gap}{(\code{numeric(1)})\cr The number of spaces to be placed between columns in the rendered table (and assumed for horizontal pagination).} -\item{round_type}{(\code{"iec"} or \code{"sas"})\cr the type of rounding to perform. iec, -the default, peforms rounding compliant with IEC 60559 (see details), while -sas performs nearest-value rounding consistent with rounding within SAS.} +\item{round_type}{(\code{"iec"}, \code{"iec_mod"} or \code{"sas"})\cr the type of rounding to perform. iec, +the default, and iec_mod peforms rounding compliant with IEC 60559 (see notes in \code{\link[=round_fmt]{round_fmt()}}), while +sas performs nearest-value rounding consistent with rounding within SAS.\cr +In addition, the rounding of a negative number that rounds to zero will be presented as 0 +(with the appropriate number of trailing zeros) for both \code{sas} and \code{iec_mod}, +while for \code{iec}, it will be presented as -0 (with the appropriate number of trailing zeros).} } \value{ If \code{file} is \code{NULL}, the full paginated and concatenated string value is returned, diff --git a/man/format_value.Rd b/man/format_value.Rd index 6060927fa..eb72fdd39 100644 --- a/man/format_value.Rd +++ b/man/format_value.Rd @@ -9,7 +9,7 @@ format_value( format = NULL, output = c("ascii", "html"), na_str = "NA", - round_type = c("iec", "sas") + round_type = valid_round_type ) } \arguments{ @@ -23,9 +23,12 @@ apply to \code{x}.} \item{na_str}{(\code{character})\cr character vector to display when the values of \code{x} are missing. If only one string is provided, it is applied for all missing values. Defaults to \code{"NA"}.} -\item{round_type}{(\code{"iec"} or \code{"sas"})\cr the type of rounding to perform. iec, -the default, peforms rounding compliant with IEC 60559 (see details), while -sas performs nearest-value rounding consistent with rounding within SAS.} +\item{round_type}{(\code{"iec"}, \code{"iec_mod"} or \code{"sas"})\cr the type of rounding to perform. iec, +the default, and iec_mod peforms rounding compliant with IEC 60559 (see notes in \code{\link[=round_fmt]{round_fmt()}}), while +sas performs nearest-value rounding consistent with rounding within SAS.\cr +In addition, the rounding of a negative number that rounds to zero will be presented as 0 +(with the appropriate number of trailing zeros) for both \code{sas} and \code{iec_mod}, +while for \code{iec}, it will be presented as -0 (with the appropriate number of trailing zeros).} } \value{ Formatted text representing the cell \code{x}. diff --git a/man/make_row_df.Rd b/man/make_row_df.Rd index 1f3183d16..44e839081 100644 --- a/man/make_row_df.Rd +++ b/man/make_row_df.Rd @@ -20,7 +20,7 @@ make_row_df( max_width = NULL, fontspec = font_spec(), col_gap = 3L, - round_type = c("iec", "sas") + round_type = valid_round_type ) \S4method{make_row_df}{MatrixPrintForm}( @@ -38,7 +38,7 @@ make_row_df( max_width = NULL, fontspec = font_spec(), col_gap = mf_colgap(tt) \%||\% 3L, - round_type = c("iec", "sas") + round_type = valid_round_type ) } \arguments{ @@ -73,9 +73,12 @@ calculating string widths and heights, as returned by \code{\link[=font_spec]{fo \item{col_gap}{(\code{numeric(1)})\cr the gap to be assumed between columns, in number of spaces with font specified by \code{fontspec}.} -\item{round_type}{(\code{"iec"} or \code{"sas"})\cr the type of rounding to perform. iec, -the default, peforms rounding compliant with IEC 60559 (see details), while -sas performs nearest-value rounding consistent with rounding within SAS.} +\item{round_type}{(\code{"iec"}, \code{"iec_mod"} or \code{"sas"})\cr the type of rounding to perform. iec, +the default, and iec_mod peforms rounding compliant with IEC 60559 (see notes in \code{\link[=round_fmt]{round_fmt()}}), while +sas performs nearest-value rounding consistent with rounding within SAS.\cr +In addition, the rounding of a negative number that rounds to zero will be presented as 0 +(with the appropriate number of trailing zeros) for both \code{sas} and \code{iec_mod}, +while for \code{iec}, it will be presented as -0 (with the appropriate number of trailing zeros).} } \value{ A \code{data.frame} of row/column-structure information used by the pagination machinery. diff --git a/man/matrix_form.Rd b/man/matrix_form.Rd index 037846abb..8318226d1 100644 --- a/man/matrix_form.Rd +++ b/man/matrix_form.Rd @@ -12,7 +12,7 @@ matrix_form( indent_size = 2, fontspec = NULL, col_gap = NULL, - round_type = c("iec", "sas") + round_type = valid_round_type ) \S4method{matrix_form}{MatrixPrintForm}( @@ -22,7 +22,7 @@ matrix_form( indent_size = 2, fontspec = NULL, col_gap = NULL, - round_type = c("iec", "sas") + round_type = valid_round_type ) } \arguments{ @@ -44,9 +44,12 @@ calculating string widths and heights, as returned by \code{\link[=font_spec]{fo \item{col_gap}{(\code{numeric(1)})\cr the gap to be assumed between columns, in number of spaces with font specified by \code{fontspec}.} -\item{round_type}{(\code{"iec"} or \code{"sas"})\cr the type of rounding to perform. iec, -the default, peforms rounding compliant with IEC 60559 (see details), while -sas performs nearest-value rounding consistent with rounding within SAS.} +\item{round_type}{(\code{"iec"}, \code{"iec_mod"} or \code{"sas"})\cr the type of rounding to perform. iec, +the default, and iec_mod peforms rounding compliant with IEC 60559 (see notes in \code{\link[=round_fmt]{round_fmt()}}), while +sas performs nearest-value rounding consistent with rounding within SAS.\cr +In addition, the rounding of a negative number that rounds to zero will be presented as 0 +(with the appropriate number of trailing zeros) for both \code{sas} and \code{iec_mod}, +while for \code{iec}, it will be presented as -0 (with the appropriate number of trailing zeros).} } \value{ A \code{\link{MatrixPrintForm}} classed list with an additional \code{nrow_header} attribute indicating the diff --git a/man/mpf_to_rtf.Rd b/man/mpf_to_rtf.Rd index a98ff27dd..94a7ab6a2 100644 --- a/man/mpf_to_rtf.Rd +++ b/man/mpf_to_rtf.Rd @@ -50,9 +50,12 @@ if the family named is not monospaced. Defaults to \code{"Courier"}.} \item{fontspec}{(\code{font_spec})\cr a font_spec object specifying the font information to use for calculating string widths and heights, as returned by \code{\link[=font_spec]{font_spec()}}.} -\item{round_type}{(\code{"iec"} or \code{"sas"})\cr the type of rounding to perform. iec, -the default, peforms rounding compliant with IEC 60559 (see details), while -sas performs nearest-value rounding consistent with rounding within SAS.} +\item{round_type}{(\code{"iec"}, \code{"iec_mod"} or \code{"sas"})\cr the type of rounding to perform. iec, +the default, and iec_mod peforms rounding compliant with IEC 60559 (see notes in \code{\link[=round_fmt]{round_fmt()}}), while +sas performs nearest-value rounding consistent with rounding within SAS.\cr +In addition, the rounding of a negative number that rounds to zero will be presented as 0 +(with the appropriate number of trailing zeros) for both \code{sas} and \code{iec_mod}, +while for \code{iec}, it will be presented as -0 (with the appropriate number of trailing zeros).} \item{...}{additional parameters passed to individual methods.} } diff --git a/man/paginate_indices.Rd b/man/paginate_indices.Rd index baea6e4ee..d7b027cf6 100644 --- a/man/paginate_indices.Rd +++ b/man/paginate_indices.Rd @@ -30,7 +30,7 @@ paginate_indices( rep_cols = num_rep_cols(obj), col_gap = 3, fontspec = font_spec(font_family, font_size, lineheight), - round_type = c("iec", "sas"), + round_type = valid_round_type, verbose = FALSE ) @@ -57,7 +57,7 @@ paginate_to_mpfs( rep_cols = NULL, col_gap = 3, fontspec = font_spec(font_family, font_size, lineheight), - round_type = c("iec", "sas"), + round_type = valid_round_type, verbose = FALSE ) @@ -85,7 +85,7 @@ diagnose_pagination( col_gap = 3, verbose = FALSE, fontspec = font_spec(font_family, font_size, lineheight), - round_type = c("iec", "sas"), + round_type = valid_round_type, ... ) } @@ -150,9 +150,12 @@ in the rendered table (and assumed for horizontal pagination).} \item{fontspec}{(\code{font_spec})\cr a font_spec object specifying the font information to use for calculating string widths and heights, as returned by \code{\link[=font_spec]{font_spec()}}.} -\item{round_type}{(\code{"iec"} or \code{"sas"})\cr the type of rounding to perform. iec, -the default, peforms rounding compliant with IEC 60559 (see details), while -sas performs nearest-value rounding consistent with rounding within SAS.} +\item{round_type}{(\code{"iec"}, \code{"iec_mod"} or \code{"sas"})\cr the type of rounding to perform. iec, +the default, and iec_mod peforms rounding compliant with IEC 60559 (see notes in \code{\link[=round_fmt]{round_fmt()}}), while +sas performs nearest-value rounding consistent with rounding within SAS.\cr +In addition, the rounding of a negative number that rounds to zero will be presented as 0 +(with the appropriate number of trailing zeros) for both \code{sas} and \code{iec_mod}, +while for \code{iec}, it will be presented as -0 (with the appropriate number of trailing zeros).} \item{verbose}{(\code{flag})\cr whether additional informative messages about the search for pagination breaks should be shown. Defaults to \code{FALSE}.} diff --git a/man/propose_column_widths.Rd b/man/propose_column_widths.Rd index 89c8260f3..58b72a723 100644 --- a/man/propose_column_widths.Rd +++ b/man/propose_column_widths.Rd @@ -8,7 +8,7 @@ propose_column_widths( x, indent_size = 2, fontspec = font_spec(), - round_type = c("iec", "sas") + round_type = valid_round_type ) } \arguments{ @@ -20,9 +20,12 @@ a \code{MatrixPrintForm} object in favor of information there.} \item{fontspec}{(\code{font_spec})\cr a font_spec object specifying the font information to use for calculating string widths and heights, as returned by \code{\link[=font_spec]{font_spec()}}.} -\item{round_type}{(\code{"iec"} or \code{"sas"})\cr the type of rounding to perform. iec, -the default, peforms rounding compliant with IEC 60559 (see details), while -sas performs nearest-value rounding consistent with rounding within SAS.} +\item{round_type}{(\code{"iec"}, \code{"iec_mod"} or \code{"sas"})\cr the type of rounding to perform. iec, +the default, and iec_mod peforms rounding compliant with IEC 60559 (see notes in \code{\link[=round_fmt]{round_fmt()}}), while +sas performs nearest-value rounding consistent with rounding within SAS.\cr +In addition, the rounding of a negative number that rounds to zero will be presented as 0 +(with the appropriate number of trailing zeros) for both \code{sas} and \code{iec_mod}, +while for \code{iec}, it will be presented as -0 (with the appropriate number of trailing zeros).} } \value{ A vector of column widths based on the content of \code{x} for use in printing and pagination. diff --git a/man/round_fmt.Rd b/man/round_fmt.Rd index cd33ea6c2..9d4f28d49 100644 --- a/man/round_fmt.Rd +++ b/man/round_fmt.Rd @@ -5,7 +5,7 @@ \alias{rounding} \title{Round and prepare a value for display} \usage{ -round_fmt(x, digits, na_str = "NA", round_type = c("iec", "sas")) +round_fmt(x, digits, na_str = "NA", round_type = valid_round_type) } \arguments{ \item{x}{(\code{numeric(1)})\cr value to format.} @@ -15,9 +15,12 @@ character value with no rounding.} \item{na_str}{(\code{string})\cr the value to return if \code{x} is \code{NA}.} -\item{round_type}{(\code{"iec"} or \code{"sas"})\cr the type of rounding to perform. iec, -the default, peforms rounding compliant with IEC 60559 (see details), while -sas performs nearest-value rounding consistent with rounding within SAS.} +\item{round_type}{(\code{"iec"}, \code{"iec_mod"} or \code{"sas"})\cr the type of rounding to perform. iec, +the default, and iec_mod peforms rounding compliant with IEC 60559 (see notes in \code{\link[=round_fmt]{round_fmt()}}), while +sas performs nearest-value rounding consistent with rounding within SAS.\cr +In addition, the rounding of a negative number that rounds to zero will be presented as 0 +(with the appropriate number of trailing zeros) for both \code{sas} and \code{iec_mod}, +while for \code{iec}, it will be presented as -0 (with the appropriate number of trailing zeros).} } \value{ A character value representing the value after rounding, containing any trailing zeros @@ -59,6 +62,9 @@ round_fmt(NA, digits = 1, na_str = "-") round_fmt(2.765923, digits = NA) round_fmt(0.845, digits = 2) round_fmt(0.845, digits = 2, round_type = "sas") +round_fmt(-0.001, digits = 2, round_type = "iec") +round_fmt(-0.001, digits = 2, round_type = "sas") +round_fmt(-0.001, digits = 2, round_type = "iec_mod") } \seealso{ diff --git a/man/tostring.Rd b/man/tostring.Rd index 0a2237141..d95bda9fb 100644 --- a/man/tostring.Rd +++ b/man/tostring.Rd @@ -16,7 +16,7 @@ toString(x, ...) hsep = NULL, fontspec = font_spec(), ttype_ok = FALSE, - round_type = c("iec", "sas") + round_type = valid_round_type ) } \arguments{ @@ -48,9 +48,12 @@ calculating string widths and heights, as returned by \code{\link[=font_spec]{fo allowed via \code{fontspec}. Defaults to \code{FALSE}. This parameter is primarily for internal testing and generally should not be set by end users.} -\item{round_type}{(\code{"iec"} or \code{"sas"})\cr the type of rounding to perform. iec, -the default, peforms rounding compliant with IEC 60559 (see details), while -sas performs nearest-value rounding consistent with rounding within SAS.} +\item{round_type}{(\code{"iec"}, \code{"iec_mod"} or \code{"sas"})\cr the type of rounding to perform. iec, +the default, and iec_mod peforms rounding compliant with IEC 60559 (see notes in \code{\link[=round_fmt]{round_fmt()}}), while +sas performs nearest-value rounding consistent with rounding within SAS.\cr +In addition, the rounding of a negative number that rounds to zero will be presented as 0 +(with the appropriate number of trailing zeros) for both \code{sas} and \code{iec_mod}, +while for \code{iec}, it will be presented as -0 (with the appropriate number of trailing zeros).} } \value{ A character string containing the ASCII rendering of the table-like object represented by \code{x}. diff --git a/man/vert_pag_indices.Rd b/man/vert_pag_indices.Rd index 276bec98d..a6bdcc39e 100644 --- a/man/vert_pag_indices.Rd +++ b/man/vert_pag_indices.Rd @@ -12,7 +12,7 @@ vert_pag_indices( rep_cols = 0L, fontspec, nosplitin = character(), - round_type = c("iec", "sas") + round_type = valid_round_type ) } \arguments{ @@ -34,9 +34,12 @@ calculating string widths and heights, as returned by \code{\link[=font_spec]{fo \item{nosplitin}{(\code{character})\cr list of names of subtables where page breaks are not allowed, regardless of other considerations. Defaults to none.} -\item{round_type}{(\code{"iec"} or \code{"sas"})\cr the type of rounding to perform. iec, -the default, peforms rounding compliant with IEC 60559 (see details), while -sas performs nearest-value rounding consistent with rounding within SAS.} +\item{round_type}{(\code{"iec"}, \code{"iec_mod"} or \code{"sas"})\cr the type of rounding to perform. iec, +the default, and iec_mod peforms rounding compliant with IEC 60559 (see notes in \code{\link[=round_fmt]{round_fmt()}}), while +sas performs nearest-value rounding consistent with rounding within SAS.\cr +In addition, the rounding of a negative number that rounds to zero will be presented as 0 +(with the appropriate number of trailing zeros) for both \code{sas} and \code{iec_mod}, +while for \code{iec}, it will be presented as -0 (with the appropriate number of trailing zeros).} } \value{ A \code{list} partitioning the vector of column indices into subsets for 1 or more horizontally paginated pages. From 2b3193c34b395fbfe38d916663599bf74eb0082f Mon Sep 17 00:00:00 2001 From: iaugusty Date: Thu, 27 Nov 2025 13:25:12 +0000 Subject: [PATCH 04/18] update NEWS --- NEWS.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/NEWS.md b/NEWS.md index bd6c87d14..3bb953df5 100644 --- a/NEWS.md +++ b/NEWS.md @@ -2,6 +2,9 @@ * Optimized pagination sub-routines to avoid `matrix_form()` calls when not needed. * Optimized pagination sub-routine `.compress_mat()` to reduce computing time for long listings. * Fixed bug in pagination of listings caused by newlines in column values. +* Added new `round_type` method, `iec_mod`. Combined all allowed values for round_type into `valid_round_type` object. +* Modified the behavior for `round_type` = `sas` for negative value that rounds to zero, by not displaying the negative sign. +* New generic `getter` and `setter` for `round_type` (`obj_round_type` and `obj_round_type<-`). ## formatters 0.5.11 * Fixed a bug in `mform_handle_newlines` that caused string matrix column names to be removed. This prevented paginated listing key column info from being repeated when vertically spanning multiple pages. From 0fbd490fb78573af47b9ad3a3ac89372c2fa6dfe Mon Sep 17 00:00:00 2001 From: github-actions <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 27 Nov 2025 14:04:21 +0000 Subject: [PATCH 05/18] [skip style] [skip vbump] Restyle files --- R/format_value.R | 2 +- R/generics.R | 3 --- tests/testthat/test-formatters.R | 1 - 3 files changed, 1 insertion(+), 5 deletions(-) diff --git a/R/format_value.R b/R/format_value.R index 8df6e679e..223469618 100644 --- a/R/format_value.R +++ b/R/format_value.R @@ -260,7 +260,7 @@ round_sas <- function(x, #' @inheritParams round_fmt #' round_iec_mod <- function(x, - digits = 0) { + digits = 0) { # perform default rounding ---------------------------------------------------- posneg <- sign(x) z <- round(abs(x), digits) diff --git a/R/generics.R b/R/generics.R index 7d4fe2fbd..fd4bbaab8 100644 --- a/R/generics.R +++ b/R/generics.R @@ -752,6 +752,3 @@ setMethod( # obj_round_type setter --------------------------------------------------------------- #' @export setGeneric("obj_round_type<-", function(obj, value) standardGeneric("obj_round_type<-")) - - - diff --git a/tests/testthat/test-formatters.R b/tests/testthat/test-formatters.R index 43d64f0c5..dcca820eb 100644 --- a/tests/testthat/test-formatters.R +++ b/tests/testthat/test-formatters.R @@ -1032,7 +1032,6 @@ test_that("sas-style rounding works", { ) - forms <- list_valid_format_labels() for (fmtset in 1:3) { for (digs in 0:3) { From edfafd9ab93309991886d543911d3dd2c8f0b4fb Mon Sep 17 00:00:00 2001 From: iaugusty Date: Thu, 27 Nov 2025 15:59:04 +0000 Subject: [PATCH 06/18] update roxygen to resolve failed check --- R/generics.R | 12 ++++++++++++ R/matrix_form.R | 1 + man/MatrixPrintForm.Rd | 2 ++ man/mpf_to_rtf.Rd | 7 +------ man/obj_round_type.Rd | 23 +++++++++++++++++++++++ man/tostring.Rd | 7 +------ 6 files changed, 40 insertions(+), 12 deletions(-) create mode 100644 man/obj_round_type.Rd diff --git a/R/generics.R b/R/generics.R index 7d4fe2fbd..72c4f858a 100644 --- a/R/generics.R +++ b/R/generics.R @@ -741,6 +741,16 @@ setMethod( # obj_round_type --------------------------------------------------------------- + +#' Rounding Type +#' +#' When called on a table-like object using the formatters framework, this method returns the +#' rounding type of the object. +#' +#' @param obj (`ANY`)\cr a table-like object. +#' +#' @return The rounding type of the object (see [round_fmt()] for details). +#' @rdname obj_round_type #' @export setGeneric("obj_round_type", function(obj) standardGeneric("obj_round_type")) @@ -750,6 +760,8 @@ setMethod( ) # obj_round_type setter --------------------------------------------------------------- +#' @rdname obj_round_type +#' @param value The new rounding type of the object (see [round_fmt()] for details) #' @export setGeneric("obj_round_type<-", function(obj, value) standardGeneric("obj_round_type<-")) diff --git a/R/matrix_form.R b/R/matrix_form.R index d1009391e..1c0036b40 100644 --- a/R/matrix_form.R +++ b/R/matrix_form.R @@ -260,6 +260,7 @@ disp_from_spans <- function(spans) { #' @param indent_size (`numeric(1)`)\cr number of spaces to be used per level of indent (if supported by #' the relevant method). Defaults to 2. #' @param rep_cols (`numeric(1)`)\cr number of columns to be repeated as context during horizontal pagination. +#' @param round_type (`"iec"`, `"iec_mod"` or `"sas"`)\cr the type of rounding to perform. See [round_fmt()] for details. #' #' @return An object of class `MatrixPrintForm`. Currently this is implemented as an S3 class inheriting #' from list with the following elements: diff --git a/man/MatrixPrintForm.Rd b/man/MatrixPrintForm.Rd index f34db80e1..107a36e46 100644 --- a/man/MatrixPrintForm.Rd +++ b/man/MatrixPrintForm.Rd @@ -111,6 +111,8 @@ the relevant method). Defaults to 2.} calculating string widths and heights, as returned by \code{\link[=font_spec]{font_spec()}}.} \item{rep_cols}{(\code{numeric(1)})\cr number of columns to be repeated as context during horizontal pagination.} + +\item{round_type}{(\code{"iec"}, \code{"iec_mod"} or \code{"sas"})\cr the type of rounding to perform. See \code{\link[=round_fmt]{round_fmt()}} for details.} } \value{ An object of class \code{MatrixPrintForm}. Currently this is implemented as an S3 class inheriting diff --git a/man/mpf_to_rtf.Rd b/man/mpf_to_rtf.Rd index 94a7ab6a2..406022add 100644 --- a/man/mpf_to_rtf.Rd +++ b/man/mpf_to_rtf.Rd @@ -50,12 +50,7 @@ if the family named is not monospaced. Defaults to \code{"Courier"}.} \item{fontspec}{(\code{font_spec})\cr a font_spec object specifying the font information to use for calculating string widths and heights, as returned by \code{\link[=font_spec]{font_spec()}}.} -\item{round_type}{(\code{"iec"}, \code{"iec_mod"} or \code{"sas"})\cr the type of rounding to perform. iec, -the default, and iec_mod peforms rounding compliant with IEC 60559 (see notes in \code{\link[=round_fmt]{round_fmt()}}), while -sas performs nearest-value rounding consistent with rounding within SAS.\cr -In addition, the rounding of a negative number that rounds to zero will be presented as 0 -(with the appropriate number of trailing zeros) for both \code{sas} and \code{iec_mod}, -while for \code{iec}, it will be presented as -0 (with the appropriate number of trailing zeros).} +\item{round_type}{(\code{"iec"}, \code{"iec_mod"} or \code{"sas"})\cr the type of rounding to perform. See \code{\link[=round_fmt]{round_fmt()}} for details.} \item{...}{additional parameters passed to individual methods.} } diff --git a/man/obj_round_type.Rd b/man/obj_round_type.Rd new file mode 100644 index 000000000..a88e8c9de --- /dev/null +++ b/man/obj_round_type.Rd @@ -0,0 +1,23 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/generics.R +\name{obj_round_type} +\alias{obj_round_type} +\alias{obj_round_type<-} +\title{Rounding Type} +\usage{ +obj_round_type(obj) + +obj_round_type(obj) <- value +} +\arguments{ +\item{obj}{(\code{ANY})\cr a table-like object.} + +\item{value}{The new rounding type of the object (see \code{\link[=round_fmt]{round_fmt()}} for details)} +} +\value{ +The rounding type of the object (see \code{\link[=round_fmt]{round_fmt()}} for details). +} +\description{ +When called on a table-like object using the formatters framework, this method returns the +rounding type of the object. +} diff --git a/man/tostring.Rd b/man/tostring.Rd index d95bda9fb..891829c96 100644 --- a/man/tostring.Rd +++ b/man/tostring.Rd @@ -48,12 +48,7 @@ calculating string widths and heights, as returned by \code{\link[=font_spec]{fo allowed via \code{fontspec}. Defaults to \code{FALSE}. This parameter is primarily for internal testing and generally should not be set by end users.} -\item{round_type}{(\code{"iec"}, \code{"iec_mod"} or \code{"sas"})\cr the type of rounding to perform. iec, -the default, and iec_mod peforms rounding compliant with IEC 60559 (see notes in \code{\link[=round_fmt]{round_fmt()}}), while -sas performs nearest-value rounding consistent with rounding within SAS.\cr -In addition, the rounding of a negative number that rounds to zero will be presented as 0 -(with the appropriate number of trailing zeros) for both \code{sas} and \code{iec_mod}, -while for \code{iec}, it will be presented as -0 (with the appropriate number of trailing zeros).} +\item{round_type}{(\code{"iec"}, \code{"iec_mod"} or \code{"sas"})\cr the type of rounding to perform. See \code{\link[=round_fmt]{round_fmt()}} for details.} } \value{ A character string containing the ASCII rendering of the table-like object represented by \code{x}. From cfb0e780abbc8e1fc8fbaadc1131d711a2e46eeb Mon Sep 17 00:00:00 2001 From: iaugusty Date: Thu, 27 Nov 2025 16:14:28 +0000 Subject: [PATCH 07/18] resolve roxygen + lintr problem --- R/format_value.R | 1 + R/generics.R | 1 + R/matrix_form.R | 3 ++- man/MatrixPrintForm.Rd | 3 ++- man/mpf_to_rtf.Rd | 3 ++- man/obj_round_type.Rd | 3 +++ man/round_fmt.Rd | 10 +++++++++- man/tostring.Rd | 3 ++- 8 files changed, 22 insertions(+), 5 deletions(-) diff --git a/R/format_value.R b/R/format_value.R index 223469618..59df2a6e4 100644 --- a/R/format_value.R +++ b/R/format_value.R @@ -157,6 +157,7 @@ sprintf_format <- function(format) { } } +#' @rdname round_fmt #' @export valid_round_type <- c("iec", "iec_mod", "sas") diff --git a/R/generics.R b/R/generics.R index 50a0b782f..65a07ba10 100644 --- a/R/generics.R +++ b/R/generics.R @@ -754,6 +754,7 @@ setMethod( #' @export setGeneric("obj_round_type", function(obj) standardGeneric("obj_round_type")) +#' @rdname obj_round_type #' @export setMethod( "obj_round_type", "MatrixPrintForm", function(obj) obj@round_type diff --git a/R/matrix_form.R b/R/matrix_form.R index 1c0036b40..419d444dd 100644 --- a/R/matrix_form.R +++ b/R/matrix_form.R @@ -260,7 +260,8 @@ disp_from_spans <- function(spans) { #' @param indent_size (`numeric(1)`)\cr number of spaces to be used per level of indent (if supported by #' the relevant method). Defaults to 2. #' @param rep_cols (`numeric(1)`)\cr number of columns to be repeated as context during horizontal pagination. -#' @param round_type (`"iec"`, `"iec_mod"` or `"sas"`)\cr the type of rounding to perform. See [round_fmt()] for details. +#' @param round_type (`"iec"`, `"iec_mod"` or `"sas"`)\cr the type of rounding to perform. +#' See [round_fmt()] for details. #' #' @return An object of class `MatrixPrintForm`. Currently this is implemented as an S3 class inheriting #' from list with the following elements: diff --git a/man/MatrixPrintForm.Rd b/man/MatrixPrintForm.Rd index 107a36e46..23df0b699 100644 --- a/man/MatrixPrintForm.Rd +++ b/man/MatrixPrintForm.Rd @@ -112,7 +112,8 @@ calculating string widths and heights, as returned by \code{\link[=font_spec]{fo \item{rep_cols}{(\code{numeric(1)})\cr number of columns to be repeated as context during horizontal pagination.} -\item{round_type}{(\code{"iec"}, \code{"iec_mod"} or \code{"sas"})\cr the type of rounding to perform. See \code{\link[=round_fmt]{round_fmt()}} for details.} +\item{round_type}{(\code{"iec"}, \code{"iec_mod"} or \code{"sas"})\cr the type of rounding to perform. +See \code{\link[=round_fmt]{round_fmt()}} for details.} } \value{ An object of class \code{MatrixPrintForm}. Currently this is implemented as an S3 class inheriting diff --git a/man/mpf_to_rtf.Rd b/man/mpf_to_rtf.Rd index 406022add..16b341214 100644 --- a/man/mpf_to_rtf.Rd +++ b/man/mpf_to_rtf.Rd @@ -50,7 +50,8 @@ if the family named is not monospaced. Defaults to \code{"Courier"}.} \item{fontspec}{(\code{font_spec})\cr a font_spec object specifying the font information to use for calculating string widths and heights, as returned by \code{\link[=font_spec]{font_spec()}}.} -\item{round_type}{(\code{"iec"}, \code{"iec_mod"} or \code{"sas"})\cr the type of rounding to perform. See \code{\link[=round_fmt]{round_fmt()}} for details.} +\item{round_type}{(\code{"iec"}, \code{"iec_mod"} or \code{"sas"})\cr the type of rounding to perform. +See \code{\link[=round_fmt]{round_fmt()}} for details.} \item{...}{additional parameters passed to individual methods.} } diff --git a/man/obj_round_type.Rd b/man/obj_round_type.Rd index a88e8c9de..7369a940b 100644 --- a/man/obj_round_type.Rd +++ b/man/obj_round_type.Rd @@ -2,11 +2,14 @@ % Please edit documentation in R/generics.R \name{obj_round_type} \alias{obj_round_type} +\alias{obj_round_type,MatrixPrintForm-method} \alias{obj_round_type<-} \title{Rounding Type} \usage{ obj_round_type(obj) +\S4method{obj_round_type}{MatrixPrintForm}(obj) + obj_round_type(obj) <- value } \arguments{ diff --git a/man/round_fmt.Rd b/man/round_fmt.Rd index 9d4f28d49..fcfa5c857 100644 --- a/man/round_fmt.Rd +++ b/man/round_fmt.Rd @@ -1,10 +1,17 @@ % Generated by roxygen2: do not edit by hand % Please edit documentation in R/format_value.R -\name{round_fmt} +\docType{data} +\name{valid_round_type} +\alias{valid_round_type} \alias{round_fmt} \alias{rounding} \title{Round and prepare a value for display} +\format{ +An object of class \code{character} of length 3. +} \usage{ +valid_round_type + round_fmt(x, digits, na_str = "NA", round_type = valid_round_type) } \arguments{ @@ -70,3 +77,4 @@ round_fmt(-0.001, digits = 2, round_type = "iec_mod") \seealso{ \code{\link[=format_value]{format_value()}}, \code{\link[=round]{round()}}, \code{\link[=sprintf]{sprintf()}} } +\keyword{datasets} diff --git a/man/tostring.Rd b/man/tostring.Rd index 891829c96..b0b88d39f 100644 --- a/man/tostring.Rd +++ b/man/tostring.Rd @@ -48,7 +48,8 @@ calculating string widths and heights, as returned by \code{\link[=font_spec]{fo allowed via \code{fontspec}. Defaults to \code{FALSE}. This parameter is primarily for internal testing and generally should not be set by end users.} -\item{round_type}{(\code{"iec"}, \code{"iec_mod"} or \code{"sas"})\cr the type of rounding to perform. See \code{\link[=round_fmt]{round_fmt()}} for details.} +\item{round_type}{(\code{"iec"}, \code{"iec_mod"} or \code{"sas"})\cr the type of rounding to perform. +See \code{\link[=round_fmt]{round_fmt()}} for details.} } \value{ A character string containing the ASCII rendering of the table-like object represented by \code{x}. From d36144c73c4d359afdc6e613ee98fa55f76d208b Mon Sep 17 00:00:00 2001 From: iaugusty Date: Mon, 1 Dec 2025 13:00:38 +0000 Subject: [PATCH 08/18] apply suggestions per review --- R/generics.R | 14 ++++++++------ R/matrix_form.R | 18 +++++++++++++----- R/mpf_exporters.R | 14 +++++--------- R/pagination.R | 12 ++++-------- R/tostring.R | 7 ++----- man/export_as_pdf.Rd | 2 +- man/export_as_rtf.Rd | 2 +- man/export_as_txt.Rd | 2 +- man/make_row_df.Rd | 4 ++-- man/matrix_form.Rd | 4 ++-- man/mpf_to_rtf.Rd | 2 +- man/obj_round_type.Rd | 5 +++++ man/paginate_indices.Rd | 6 +++--- man/propose_column_widths.Rd | 2 +- man/test_matrix_form.Rd | 9 +++++++-- man/tostring.Rd | 2 +- man/vert_pag_indices.Rd | 2 +- tests/testthat/test-formatters.R | 20 ++++++++++++++++++++ 18 files changed, 78 insertions(+), 49 deletions(-) diff --git a/R/generics.R b/R/generics.R index 65a07ba10..7156a5df3 100644 --- a/R/generics.R +++ b/R/generics.R @@ -68,8 +68,7 @@ setGeneric("make_row_df", function(tt, colwidths = NULL, visible_only = TRUE, max_width = NULL, fontspec = font_spec(), col_gap = 3L, - round_type = valid_round_type) { - round_type <- match.arg(round_type) + round_type = obj_round_type(tt)) { standardGeneric("make_row_df") }) @@ -86,7 +85,7 @@ setMethod("make_row_df", "MatrixPrintForm", function(tt, colwidths = NULL, visib max_width = NULL, fontspec = font_spec(), col_gap = mf_colgap(tt) %||% 3L, - round_type = valid_round_type) { + round_type = obj_round_type(tt)) { msg <- paste0( "make_row_df can be used only on {rtables} table objects, and not on `matrix_form`-", "generated objects (MatrixPrintForm)." @@ -128,7 +127,7 @@ setGeneric("matrix_form", function(obj, indent_size = 2, fontspec = NULL, col_gap = NULL, - round_type = valid_round_type) { + round_type = obj_round_type(obj)) { standardGeneric("matrix_form") }) @@ -141,7 +140,7 @@ setMethod("matrix_form", "MatrixPrintForm", function(obj, indent_size = 2, fontspec = NULL, col_gap = NULL, - round_type = valid_round_type) { + round_type = obj_round_type(obj)) { if (!is.null(fontspec)) { mf_fontspec(obj) <- fontspec } @@ -757,11 +756,14 @@ setGeneric("obj_round_type", function(obj) standardGeneric("obj_round_type")) #' @rdname obj_round_type #' @export setMethod( - "obj_round_type", "MatrixPrintForm", function(obj) obj@round_type + "obj_round_type", "MatrixPrintForm", function(obj) obj$round_type ) # obj_round_type setter --------------------------------------------------------------- #' @rdname obj_round_type #' @param value The new rounding type of the object (see [round_fmt()] for details) +#' @note The setter method should only be created/used for pre-MatrixPrintForm objects, +#' as resetting the rounding type after rounding occurs (which is during MPF creation) +#' will not effect output when printing/exporting. #' @export setGeneric("obj_round_type<-", function(obj, value) standardGeneric("obj_round_type<-")) diff --git a/R/matrix_form.R b/R/matrix_form.R index 419d444dd..339b7dc0f 100644 --- a/R/matrix_form.R +++ b/R/matrix_form.R @@ -920,6 +920,8 @@ mf_has_rlabels <- function(mf) ncol(mf$strings) > mf_ncol(mf) #' @param num_rep_cols (`numeric(1)`)\cr Number of columns to be treated as repeating columns. #' Defaults to `0` for `basic_matrix_form` and `length(keycols)` for #' `basic_listing_mf`. Note repeating columns are separate from row labels if present. +#' @param round_type (`"iec"`, `"iec_mod"` or `"sas"`)\cr the type of rounding to perform. +#' See [round_fmt()] for details. #' #' @return A valid `MatrixPrintForm` object representing `df` that is ready for #' ASCII rendering. @@ -955,7 +957,8 @@ basic_matrix_form <- function(df, fontspec = font_spec(), split_labels = NULL, data_labels = NULL, - num_rep_cols = 0L) { + num_rep_cols = 0L, + round_type = valid_round_type) { checkmate::assert_data_frame(df) checkmate::assert_flag(indent_rownames) checkmate::assert_character(parent_path, null.ok = TRUE) @@ -963,6 +966,7 @@ basic_matrix_form <- function(df, checkmate::assert_flag(add_decoration) checkmate::assert_character(split_labels, null.ok = TRUE) checkmate::assert_character(data_labels, null.ok = TRUE) + round_type <- match.arg(round_type) # Some defaults row_classes <- "DataRow" # Default for all rows @@ -1021,7 +1025,7 @@ basic_matrix_form <- function(df, bodystrs <- mapply(function(x, coli_fmt) { coli_fmt[coli_fmt == "-"] <- "xx" sapply(seq_along(x), function(y) { - format_value(x[y], format = coli_fmt[y]) + format_value(x[y], format = coli_fmt[y], round_type = round_type) }) }, x = df, coli_fmt = fmts) @@ -1116,7 +1120,8 @@ basic_matrix_form <- function(df, fontspec = fontspec, col_gap = 3, indent_size = indent_size, - rep_cols = num_rep_cols + rep_cols = num_rep_cols, + round_type = round_type ) # Check for ncols @@ -1151,7 +1156,9 @@ basic_matrix_form <- function(df, basic_listing_mf <- function(df, keycols = names(df)[1], add_decoration = TRUE, - fontspec = font_spec()) { + fontspec = font_spec(), + round_type = valid_round_type) { + round_type <- match.arg(round_type) checkmate::assert_data_frame(df) checkmate::assert_subset(keycols, colnames(df)) @@ -1161,7 +1168,8 @@ basic_listing_mf <- function(df, ignore_rownames = TRUE, add_decoration = add_decoration, num_rep_cols = length(keycols), - fontspec = fontspec + fontspec = fontspec, + round_type = round_type ) # keycols addition to MatrixPrintForm (should happen in the constructor) diff --git a/R/mpf_exporters.R b/R/mpf_exporters.R index 0864dab74..873787f40 100644 --- a/R/mpf_exporters.R +++ b/R/mpf_exporters.R @@ -60,8 +60,7 @@ export_as_txt <- function(x, page_num = default_page_number(), fontspec = font_spec(font_family, font_size, lineheight), col_gap = 3, - round_type = valid_round_type) { - round_type <- match.arg(round_type) + round_type = obj_round_type(x)) { # Processing lists of tables or listings if (.is_list_of_tables_or_listings(x)) { if (isFALSE(paginate)) { @@ -187,8 +186,7 @@ prep_header_line <- function(mf, i) { ## ) ## } -mpf_to_dfbody <- function(mpf, colwidths, fontspec, round_type = valid_round_type) { - round_type <- match.arg(round_type) +mpf_to_dfbody <- function(mpf, colwidths, fontspec, round_type = obj_round_type(mpf)) { mf <- matrix_form(mpf, indent_rownames = TRUE, fontspec = fontspec, round_type = round_type) nlr <- mf_nlheader(mf) if (is.null(colwidths)) { @@ -234,7 +232,7 @@ mpf_to_rtf <- function(mpf, font_size = 8, lineheight = 1, fontspec = font_spec(font_family, font_size, lineheight), - round_type = round_type, + round_type = obj_round_type(mpf), ...) { if (!requireNamespace("r2rtf")) { stop("RTF export requires the 'r2rtf' package, please install it.") @@ -422,9 +420,8 @@ export_as_rtf <- function(x, lineheight = 1, fontspec = font_spec(font_family, font_size, lineheight), paginate = TRUE, - round_type = valid_round_type, + round_type = obj_round_type(x), ...) { - round_type <- match.arg(round_type) # Processing lists of tables or listings if (.is_list_of_tables_or_listings(x)) { if (isFALSE(paginate)) { @@ -569,8 +566,7 @@ export_as_pdf <- function(x, colwidths = NULL, fontspec = font_spec(font_family, font_size, lineheight), ttype_ok = FALSE, - round_type = valid_round_type) { - round_type <- match.arg(round_type) + round_type = obj_round_type(x)) { ## this has to happen at the very beginning before the first use of fontspec ## which happens in the default value of colwidths. yay lazy evaluation... if (missing(font_size) && !missing(fontsize)) { diff --git a/R/pagination.R b/R/pagination.R index b09e1feff..a0a61543c 100644 --- a/R/pagination.R +++ b/R/pagination.R @@ -590,8 +590,7 @@ vert_pag_indices <- function(mf, rep_cols = 0L, fontspec, nosplitin = character(), - round_type = valid_round_type) { - round_type <- match.arg(round_type) + round_type = obj_round_type(mf)) { if (is.list(nosplitin)) { nosplitin <- nosplitin[["cols"]] } @@ -1002,9 +1001,8 @@ paginate_indices <- function(obj, rep_cols = num_rep_cols(obj), col_gap = 3, fontspec = font_spec(font_family, font_size, lineheight), - round_type = valid_round_type, + round_type = obj_round_type(obj), verbose = FALSE) { - round_type <- match.arg(round_type) ## this preserves backwards compatibility ## could start deprecation cycle of char input if (is.character(nosplitin)) { @@ -1203,9 +1201,8 @@ paginate_to_mpfs <- function(obj, # col_gap = 3, # this could be change in default - breaking change col_gap = 3, fontspec = font_spec(font_family, font_size, lineheight), - round_type = valid_round_type, + round_type = obj_round_type(obj), verbose = FALSE) { - round_type <- match.arg(round_type) newdev <- open_font_dev(fontspec) if (newdev) { on.exit(close_font_dev()) @@ -1505,9 +1502,8 @@ diagnose_pagination <- function(obj, font_size, lineheight ), - round_type = valid_round_type, + round_type = obj_round_type(obj), ...) { - round_type <- match.arg(round_type) new_dev <- open_font_dev(fontspec) if (new_dev) { on.exit(close_font_dev()) diff --git a/R/tostring.R b/R/tostring.R index c4d280fab..bf46503a7 100644 --- a/R/tostring.R +++ b/R/tostring.R @@ -646,9 +646,8 @@ setMethod("toString", "MatrixPrintForm", function(x, hsep = NULL, fontspec = font_spec(), ttype_ok = FALSE, - round_type = valid_round_type) { + round_type = obj_round_type(x)) { checkmate::assert_flag(tf_wrap) - round_type <- match.arg(round_type) ## we are going to use the pdf device and grid to understand the actual ## print width of things given our font family and font size @@ -1380,9 +1379,7 @@ spans_to_viscell <- function(spans) { propose_column_widths <- function(x, indent_size = 2, fontspec = font_spec(), - round_type = valid_round_type) { - round_type <- match.arg(round_type) - + round_type = obj_round_type(x)) { new_dev <- open_font_dev(fontspec) if (new_dev) { on.exit(close_font_dev()) diff --git a/man/export_as_pdf.Rd b/man/export_as_pdf.Rd index 7581e735f..ddaccb2c5 100644 --- a/man/export_as_pdf.Rd +++ b/man/export_as_pdf.Rd @@ -31,7 +31,7 @@ export_as_pdf( colwidths = NULL, fontspec = font_spec(font_family, font_size, lineheight), ttype_ok = FALSE, - round_type = valid_round_type + round_type = obj_round_type(x) ) } \arguments{ diff --git a/man/export_as_rtf.Rd b/man/export_as_rtf.Rd index b6a8ca3b9..f5897b4d1 100644 --- a/man/export_as_rtf.Rd +++ b/man/export_as_rtf.Rd @@ -18,7 +18,7 @@ export_as_rtf( lineheight = 1, fontspec = font_spec(font_family, font_size, lineheight), paginate = TRUE, - round_type = valid_round_type, + round_type = obj_round_type(x), ... ) } diff --git a/man/export_as_txt.Rd b/man/export_as_txt.Rd index d63685d9e..5da9949f4 100644 --- a/man/export_as_txt.Rd +++ b/man/export_as_txt.Rd @@ -32,7 +32,7 @@ export_as_txt( page_num = default_page_number(), fontspec = font_spec(font_family, font_size, lineheight), col_gap = 3, - round_type = valid_round_type + round_type = obj_round_type(x) ) } \arguments{ diff --git a/man/make_row_df.Rd b/man/make_row_df.Rd index 44e839081..9698783a8 100644 --- a/man/make_row_df.Rd +++ b/man/make_row_df.Rd @@ -20,7 +20,7 @@ make_row_df( max_width = NULL, fontspec = font_spec(), col_gap = 3L, - round_type = valid_round_type + round_type = obj_round_type(tt) ) \S4method{make_row_df}{MatrixPrintForm}( @@ -38,7 +38,7 @@ make_row_df( max_width = NULL, fontspec = font_spec(), col_gap = mf_colgap(tt) \%||\% 3L, - round_type = valid_round_type + round_type = obj_round_type(tt) ) } \arguments{ diff --git a/man/matrix_form.Rd b/man/matrix_form.Rd index 8318226d1..08751810b 100644 --- a/man/matrix_form.Rd +++ b/man/matrix_form.Rd @@ -12,7 +12,7 @@ matrix_form( indent_size = 2, fontspec = NULL, col_gap = NULL, - round_type = valid_round_type + round_type = obj_round_type(obj) ) \S4method{matrix_form}{MatrixPrintForm}( @@ -22,7 +22,7 @@ matrix_form( indent_size = 2, fontspec = NULL, col_gap = NULL, - round_type = valid_round_type + round_type = obj_round_type(obj) ) } \arguments{ diff --git a/man/mpf_to_rtf.Rd b/man/mpf_to_rtf.Rd index 16b341214..c49e006be 100644 --- a/man/mpf_to_rtf.Rd +++ b/man/mpf_to_rtf.Rd @@ -16,7 +16,7 @@ mpf_to_rtf( font_size = 8, lineheight = 1, fontspec = font_spec(font_family, font_size, lineheight), - round_type = round_type, + round_type = obj_round_type(mpf), ... ) } diff --git a/man/obj_round_type.Rd b/man/obj_round_type.Rd index 7369a940b..708b9fcf1 100644 --- a/man/obj_round_type.Rd +++ b/man/obj_round_type.Rd @@ -24,3 +24,8 @@ The rounding type of the object (see \code{\link[=round_fmt]{round_fmt()}} for d When called on a table-like object using the formatters framework, this method returns the rounding type of the object. } +\note{ +The setter method should only be created/used for pre-MatrixPrintForm objects, +as resetting the rounding type after rounding occurs (which is during MPF creation) +will not effect output when printing/exporting. +} diff --git a/man/paginate_indices.Rd b/man/paginate_indices.Rd index d7b027cf6..5998de5b9 100644 --- a/man/paginate_indices.Rd +++ b/man/paginate_indices.Rd @@ -30,7 +30,7 @@ paginate_indices( rep_cols = num_rep_cols(obj), col_gap = 3, fontspec = font_spec(font_family, font_size, lineheight), - round_type = valid_round_type, + round_type = obj_round_type(obj), verbose = FALSE ) @@ -57,7 +57,7 @@ paginate_to_mpfs( rep_cols = NULL, col_gap = 3, fontspec = font_spec(font_family, font_size, lineheight), - round_type = valid_round_type, + round_type = obj_round_type(obj), verbose = FALSE ) @@ -85,7 +85,7 @@ diagnose_pagination( col_gap = 3, verbose = FALSE, fontspec = font_spec(font_family, font_size, lineheight), - round_type = valid_round_type, + round_type = obj_round_type(obj), ... ) } diff --git a/man/propose_column_widths.Rd b/man/propose_column_widths.Rd index 58b72a723..9434dab0a 100644 --- a/man/propose_column_widths.Rd +++ b/man/propose_column_widths.Rd @@ -8,7 +8,7 @@ propose_column_widths( x, indent_size = 2, fontspec = font_spec(), - round_type = valid_round_type + round_type = obj_round_type(x) ) } \arguments{ diff --git a/man/test_matrix_form.Rd b/man/test_matrix_form.Rd index 7431af406..2180ec2d3 100644 --- a/man/test_matrix_form.Rd +++ b/man/test_matrix_form.Rd @@ -15,14 +15,16 @@ basic_matrix_form( fontspec = font_spec(), split_labels = NULL, data_labels = NULL, - num_rep_cols = 0L + num_rep_cols = 0L, + round_type = valid_round_type ) basic_listing_mf( df, keycols = names(df)[1], add_decoration = TRUE, - fontspec = font_spec() + fontspec = font_spec(), + round_type = valid_round_type ) } \arguments{ @@ -58,6 +60,9 @@ for more information.} Defaults to \code{0} for \code{basic_matrix_form} and \code{length(keycols)} for \code{basic_listing_mf}. Note repeating columns are separate from row labels if present.} +\item{round_type}{(\code{"iec"}, \code{"iec_mod"} or \code{"sas"})\cr the type of rounding to perform. +See \code{\link[=round_fmt]{round_fmt()}} for details.} + \item{keycols}{(\code{character})\cr a vector of \code{df} column names that are printed first and for which repeated values are assigned \code{""}. This format is characteristic of a listing matrix form.} } diff --git a/man/tostring.Rd b/man/tostring.Rd index b0b88d39f..36ccb0517 100644 --- a/man/tostring.Rd +++ b/man/tostring.Rd @@ -16,7 +16,7 @@ toString(x, ...) hsep = NULL, fontspec = font_spec(), ttype_ok = FALSE, - round_type = valid_round_type + round_type = obj_round_type(x) ) } \arguments{ diff --git a/man/vert_pag_indices.Rd b/man/vert_pag_indices.Rd index a6bdcc39e..a63879513 100644 --- a/man/vert_pag_indices.Rd +++ b/man/vert_pag_indices.Rd @@ -12,7 +12,7 @@ vert_pag_indices( rep_cols = 0L, fontspec, nosplitin = character(), - round_type = valid_round_type + round_type = obj_round_type(mf) ) } \arguments{ diff --git a/tests/testthat/test-formatters.R b/tests/testthat/test-formatters.R index d31b9cd7c..532705d07 100644 --- a/tests/testthat/test-formatters.R +++ b/tests/testthat/test-formatters.R @@ -1116,3 +1116,23 @@ test_that("na_str works when having multiple NAs and multiple values to be chang "a (1.0 - b)" ) }) + +test_that("Methods for obj_round_type", { + inputdf <- mtcars + obj_format(inputdf$wt) <- "xx.xx" + dfmf <- basic_matrix_form(inputdf) + dfmf2 <- basic_matrix_form(inputdf, round_type = "sas") + + expect_identical(obj_round_type(dfmf), "iec") + expect_identical(obj_round_type(dfmf2), "sas") + + # check actual rounding + df_iec <- dfmf$strings[1+(1:nrow(inputdf)),"wt"] + df_sas <- dfmf2$strings[1+(1:nrow(inputdf)),"wt"] + + fmt_iec <- sapply(inputdf[,"wt"], function(x) format_value(x, format = "xx.xx", round_type = "iec")) + fmt_sas <- sapply(inputdf[,"wt"], function(x) format_value(x, format = "xx.xx", round_type = "sas")) + expect_identical(df_iec, fmt_iec) + expect_identical(df_sas, fmt_sas) + +}) From 218820a3218c493ccee0b14b0f4b2dccb24e0d25 Mon Sep 17 00:00:00 2001 From: iaugusty Date: Mon, 1 Dec 2025 15:44:55 +0000 Subject: [PATCH 09/18] default for round_type when input can be a list --- R/mpf_exporters.R | 11 ++++++++--- R/pagination.R | 2 +- man/export_as_pdf.Rd | 2 +- man/export_as_rtf.Rd | 2 +- man/export_as_txt.Rd | 2 +- man/paginate_indices.Rd | 2 +- 6 files changed, 13 insertions(+), 8 deletions(-) diff --git a/R/mpf_exporters.R b/R/mpf_exporters.R index 873787f40..f3fb4dda6 100644 --- a/R/mpf_exporters.R +++ b/R/mpf_exporters.R @@ -2,6 +2,11 @@ !(is.null(page_type) && is.null(pg_width) && is.null(pg_height) && is.null(cpp) && is.null(lpp)) } +.get_first_element_of_object <- function(x) { + if (is(x, "list")) return (x[[1]]) + else return (x) +} + #' Export a table-like object to plain (ASCII) text with page breaks #' #' This function converts `x` to a `MatrixPrintForm` object via [matrix_form()], paginates it @@ -60,7 +65,7 @@ export_as_txt <- function(x, page_num = default_page_number(), fontspec = font_spec(font_family, font_size, lineheight), col_gap = 3, - round_type = obj_round_type(x)) { + round_type = obj_round_type(.get_first_element_of_object(x))) { # Processing lists of tables or listings if (.is_list_of_tables_or_listings(x)) { if (isFALSE(paginate)) { @@ -420,7 +425,7 @@ export_as_rtf <- function(x, lineheight = 1, fontspec = font_spec(font_family, font_size, lineheight), paginate = TRUE, - round_type = obj_round_type(x), + round_type = obj_round_type(.get_first_element_of_object(x)), ...) { # Processing lists of tables or listings if (.is_list_of_tables_or_listings(x)) { @@ -566,7 +571,7 @@ export_as_pdf <- function(x, colwidths = NULL, fontspec = font_spec(font_family, font_size, lineheight), ttype_ok = FALSE, - round_type = obj_round_type(x)) { + round_type = obj_round_type(.get_first_element_of_object(x))) { ## this has to happen at the very beginning before the first use of fontspec ## which happens in the default value of colwidths. yay lazy evaluation... if (missing(font_size) && !missing(fontsize)) { diff --git a/R/pagination.R b/R/pagination.R index a0a61543c..0f0e6f027 100644 --- a/R/pagination.R +++ b/R/pagination.R @@ -1201,7 +1201,7 @@ paginate_to_mpfs <- function(obj, # col_gap = 3, # this could be change in default - breaking change col_gap = 3, fontspec = font_spec(font_family, font_size, lineheight), - round_type = obj_round_type(obj), + round_type = obj_round_type(.get_first_element_of_object(obj)), verbose = FALSE) { newdev <- open_font_dev(fontspec) if (newdev) { diff --git a/man/export_as_pdf.Rd b/man/export_as_pdf.Rd index ddaccb2c5..ffce0d9f3 100644 --- a/man/export_as_pdf.Rd +++ b/man/export_as_pdf.Rd @@ -31,7 +31,7 @@ export_as_pdf( colwidths = NULL, fontspec = font_spec(font_family, font_size, lineheight), ttype_ok = FALSE, - round_type = obj_round_type(x) + round_type = obj_round_type(.get_first_element_of_object(x)) ) } \arguments{ diff --git a/man/export_as_rtf.Rd b/man/export_as_rtf.Rd index f5897b4d1..6408928af 100644 --- a/man/export_as_rtf.Rd +++ b/man/export_as_rtf.Rd @@ -18,7 +18,7 @@ export_as_rtf( lineheight = 1, fontspec = font_spec(font_family, font_size, lineheight), paginate = TRUE, - round_type = obj_round_type(x), + round_type = obj_round_type(.get_first_element_of_object(x)), ... ) } diff --git a/man/export_as_txt.Rd b/man/export_as_txt.Rd index 5da9949f4..0ad220971 100644 --- a/man/export_as_txt.Rd +++ b/man/export_as_txt.Rd @@ -32,7 +32,7 @@ export_as_txt( page_num = default_page_number(), fontspec = font_spec(font_family, font_size, lineheight), col_gap = 3, - round_type = obj_round_type(x) + round_type = obj_round_type(.get_first_element_of_object(x)) ) } \arguments{ diff --git a/man/paginate_indices.Rd b/man/paginate_indices.Rd index 5998de5b9..005e4dd07 100644 --- a/man/paginate_indices.Rd +++ b/man/paginate_indices.Rd @@ -57,7 +57,7 @@ paginate_to_mpfs( rep_cols = NULL, col_gap = 3, fontspec = font_spec(font_family, font_size, lineheight), - round_type = obj_round_type(obj), + round_type = obj_round_type(.get_first_element_of_object(obj)), verbose = FALSE ) From b788905ae9b4e4201797c118b8d97f4cf0eefa7e Mon Sep 17 00:00:00 2001 From: github-actions <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 1 Dec 2025 16:03:01 +0000 Subject: [PATCH 10/18] [skip style] [skip vbump] Restyle files --- R/mpf_exporters.R | 7 +++++-- tests/testthat/test-formatters.R | 9 ++++----- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/R/mpf_exporters.R b/R/mpf_exporters.R index f3fb4dda6..b27e9479b 100644 --- a/R/mpf_exporters.R +++ b/R/mpf_exporters.R @@ -3,8 +3,11 @@ } .get_first_element_of_object <- function(x) { - if (is(x, "list")) return (x[[1]]) - else return (x) + if (is(x, "list")) { + return(x[[1]]) + } else { + return(x) + } } #' Export a table-like object to plain (ASCII) text with page breaks diff --git a/tests/testthat/test-formatters.R b/tests/testthat/test-formatters.R index 532705d07..8eaed646b 100644 --- a/tests/testthat/test-formatters.R +++ b/tests/testthat/test-formatters.R @@ -1127,12 +1127,11 @@ test_that("Methods for obj_round_type", { expect_identical(obj_round_type(dfmf2), "sas") # check actual rounding - df_iec <- dfmf$strings[1+(1:nrow(inputdf)),"wt"] - df_sas <- dfmf2$strings[1+(1:nrow(inputdf)),"wt"] + df_iec <- dfmf$strings[1 + (1:nrow(inputdf)), "wt"] + df_sas <- dfmf2$strings[1 + (1:nrow(inputdf)), "wt"] - fmt_iec <- sapply(inputdf[,"wt"], function(x) format_value(x, format = "xx.xx", round_type = "iec")) - fmt_sas <- sapply(inputdf[,"wt"], function(x) format_value(x, format = "xx.xx", round_type = "sas")) + fmt_iec <- sapply(inputdf[, "wt"], function(x) format_value(x, format = "xx.xx", round_type = "iec")) + fmt_sas <- sapply(inputdf[, "wt"], function(x) format_value(x, format = "xx.xx", round_type = "sas")) expect_identical(df_iec, fmt_iec) expect_identical(df_sas, fmt_sas) - }) From 808511c5cfcbfdae9e5013642e0a48b4bdff91a1 Mon Sep 17 00:00:00 2001 From: iaugusty Date: Mon, 1 Dec 2025 16:07:02 +0000 Subject: [PATCH 11/18] WORDLIST update --- inst/WORDLIST | 2 ++ 1 file changed, 2 insertions(+) diff --git a/inst/WORDLIST b/inst/WORDLIST index fa54687d7..29b31d724 100644 --- a/inst/WORDLIST +++ b/inst/WORDLIST @@ -7,6 +7,7 @@ IEC LPP MPF MPFs +MatrixPrintForm ORCID RTF Rua @@ -24,6 +25,7 @@ paginations pathing peforms pre +repo sas subtable subtables From aad4f071c2b13059803582ef45324603dbf70bc6 Mon Sep 17 00:00:00 2001 From: iaugusty Date: Mon, 1 Dec 2025 16:25:29 +0000 Subject: [PATCH 12/18] empty commit From eb17984b3f8ba4d6e8926dd358037e8358073624 Mon Sep 17 00:00:00 2001 From: iaugusty Date: Mon, 1 Dec 2025 16:33:59 +0000 Subject: [PATCH 13/18] resolve lintr issues --- R/mpf_exporters.R | 4 ++-- tests/testthat/test-formatters.R | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/R/mpf_exporters.R b/R/mpf_exporters.R index b27e9479b..9280edbd8 100644 --- a/R/mpf_exporters.R +++ b/R/mpf_exporters.R @@ -4,9 +4,9 @@ .get_first_element_of_object <- function(x) { if (is(x, "list")) { - return(x[[1]]) + x[[1]] } else { - return(x) + x } } diff --git a/tests/testthat/test-formatters.R b/tests/testthat/test-formatters.R index 8eaed646b..84a463073 100644 --- a/tests/testthat/test-formatters.R +++ b/tests/testthat/test-formatters.R @@ -1127,8 +1127,8 @@ test_that("Methods for obj_round_type", { expect_identical(obj_round_type(dfmf2), "sas") # check actual rounding - df_iec <- dfmf$strings[1 + (1:nrow(inputdf)), "wt"] - df_sas <- dfmf2$strings[1 + (1:nrow(inputdf)), "wt"] + df_iec <- dfmf$strings[1 + seq_len(nrow(inputdf)), "wt"] + df_sas <- dfmf2$strings[1 + seq_len(nrow(inputdf)), "wt"] fmt_iec <- sapply(inputdf[, "wt"], function(x) format_value(x, format = "xx.xx", round_type = "iec")) fmt_sas <- sapply(inputdf[, "wt"], function(x) format_value(x, format = "xx.xx", round_type = "sas")) From 2f0906e271d258964187e75cb6f41a3954a5cd70 Mon Sep 17 00:00:00 2001 From: iaugusty Date: Fri, 5 Dec 2025 13:04:31 +0000 Subject: [PATCH 14/18] address review comments Gabe --- NAMESPACE | 1 + R/format_value.R | 6 ++++-- R/generics.R | 31 +++++++++++++++++++++++++++++++ R/matrix_form.R | 6 ++++-- R/mpf_exporters.R | 14 +++----------- R/pagination.R | 2 +- inst/WORDLIST | 1 - man/MatrixPrintForm.Rd | 3 ++- man/export_as_pdf.Rd | 8 +++++--- man/export_as_rtf.Rd | 8 +++++--- man/export_as_txt.Rd | 8 +++++--- man/format_value.Rd | 6 ++++-- man/make_row_df.Rd | 6 ++++-- man/matrix_form.Rd | 6 ++++-- man/mpf_to_rtf.Rd | 3 ++- man/obj_round_type.Rd | 12 ++++++++++++ man/paginate_indices.Rd | 8 +++++--- man/propose_column_widths.Rd | 6 ++++-- man/round_fmt.Rd | 6 ++++-- man/test_matrix_form.Rd | 3 ++- man/tostring.Rd | 3 ++- man/vert_pag_indices.Rd | 6 ++++-- tests/testthat/test-formatters.R | 23 +++++++++++++++++++++++ 23 files changed, 131 insertions(+), 45 deletions(-) diff --git a/NAMESPACE b/NAMESPACE index 35f84dc5b..228966891 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -126,6 +126,7 @@ exportMethods("obj_align<-") exportMethods("obj_format<-") exportMethods("obj_label<-") exportMethods("obj_na_str<-") +exportMethods("obj_round_type<-") exportMethods("page_titles<-") exportMethods("prov_footer<-") exportMethods("subtitles<-") diff --git a/R/format_value.R b/R/format_value.R index 6ae148656..a6c09f2da 100644 --- a/R/format_value.R +++ b/R/format_value.R @@ -177,8 +177,10 @@ valid_round_type <- c("iec", "iec_mod", "sas") #' @param digits (`numeric(1)`)\cr number of digits to round to, or `NA` to convert to a #' character value with no rounding. #' @param na_str (`string`)\cr the value to return if `x` is `NA`. -#' @param round_type (`"iec"`, `"iec_mod"` or `"sas"`)\cr the type of rounding to perform. iec, -#' the default, and iec_mod peforms rounding compliant with IEC 60559 (see notes in [round_fmt()]), while +#' @param round_type (`string`)\cr . +#' \cr The type of rounding to perform. Allowed values: (`"iec"`, `"iec_mod"` or `"sas"`) +#' \cr iec, the default, and iec_mod performs rounding compliant with IEC 60559 +#' (see notes in [round_fmt()]), while #' sas performs nearest-value rounding consistent with rounding within SAS.\cr #' In addition, the rounding of a negative number that rounds to zero will be presented as 0 #' (with the appropriate number of trailing zeros) for both `sas` and `iec_mod`, diff --git a/R/generics.R b/R/generics.R index 7156a5df3..c05e903ff 100644 --- a/R/generics.R +++ b/R/generics.R @@ -759,6 +759,15 @@ setMethod( "obj_round_type", "MatrixPrintForm", function(obj) obj$round_type ) +#' @rdname obj_round_type +#' @export +setMethod("obj_round_type", "list", function(obj) { + if (!.is_list_of_tables_or_listings(obj)) { + stop("got a list that doesn't appear to contain (only) tables or listings") + } + obj_round_type(obj[[1]]) +}) + # obj_round_type setter --------------------------------------------------------------- #' @rdname obj_round_type #' @param value The new rounding type of the object (see [round_fmt()] for details) @@ -767,3 +776,25 @@ setMethod( #' will not effect output when printing/exporting. #' @export setGeneric("obj_round_type<-", function(obj, value) standardGeneric("obj_round_type<-")) + +#' @rdname obj_round_type +#' @export +setMethod("obj_round_type<-", "list", function(obj, value) { + if (!.is_list_of_tables_or_listings(obj)) { + stop("got a list that doesn't appear to contain (only) tables or listings") + } + obj <- lapply(obj, function(x) { + obj_round_type(x) <- value + x + }) + obj +}) + +#' @rdname obj_round_type +#' @export +#' @note round_type cannot not be updated on a `MatrixPrintForm` object +#' as rounding occurs during creation of MatrixPrintForm object +setMethod("obj_round_type<-", "MatrixPrintForm", function(obj, value) { + message("'obj_round_type<-' should not be applied on class `MatrixPrintForm`") + obj +}) diff --git a/R/matrix_form.R b/R/matrix_form.R index 339b7dc0f..a884c32c6 100644 --- a/R/matrix_form.R +++ b/R/matrix_form.R @@ -260,7 +260,8 @@ disp_from_spans <- function(spans) { #' @param indent_size (`numeric(1)`)\cr number of spaces to be used per level of indent (if supported by #' the relevant method). Defaults to 2. #' @param rep_cols (`numeric(1)`)\cr number of columns to be repeated as context during horizontal pagination. -#' @param round_type (`"iec"`, `"iec_mod"` or `"sas"`)\cr the type of rounding to perform. +#' @param round_type (`string`)\cr +#' The type of rounding to perform. Allowed values: (`"iec"`, `"iec_mod"` or `"sas"`) #' See [round_fmt()] for details. #' #' @return An object of class `MatrixPrintForm`. Currently this is implemented as an S3 class inheriting @@ -920,7 +921,8 @@ mf_has_rlabels <- function(mf) ncol(mf$strings) > mf_ncol(mf) #' @param num_rep_cols (`numeric(1)`)\cr Number of columns to be treated as repeating columns. #' Defaults to `0` for `basic_matrix_form` and `length(keycols)` for #' `basic_listing_mf`. Note repeating columns are separate from row labels if present. -#' @param round_type (`"iec"`, `"iec_mod"` or `"sas"`)\cr the type of rounding to perform. +#' @param round_type (`string`)\cr +#' The type of rounding to perform. Allowed values: (`"iec"`, `"iec_mod"` or `"sas"`) #' See [round_fmt()] for details. #' #' @return A valid `MatrixPrintForm` object representing `df` that is ready for diff --git a/R/mpf_exporters.R b/R/mpf_exporters.R index 9280edbd8..873787f40 100644 --- a/R/mpf_exporters.R +++ b/R/mpf_exporters.R @@ -2,14 +2,6 @@ !(is.null(page_type) && is.null(pg_width) && is.null(pg_height) && is.null(cpp) && is.null(lpp)) } -.get_first_element_of_object <- function(x) { - if (is(x, "list")) { - x[[1]] - } else { - x - } -} - #' Export a table-like object to plain (ASCII) text with page breaks #' #' This function converts `x` to a `MatrixPrintForm` object via [matrix_form()], paginates it @@ -68,7 +60,7 @@ export_as_txt <- function(x, page_num = default_page_number(), fontspec = font_spec(font_family, font_size, lineheight), col_gap = 3, - round_type = obj_round_type(.get_first_element_of_object(x))) { + round_type = obj_round_type(x)) { # Processing lists of tables or listings if (.is_list_of_tables_or_listings(x)) { if (isFALSE(paginate)) { @@ -428,7 +420,7 @@ export_as_rtf <- function(x, lineheight = 1, fontspec = font_spec(font_family, font_size, lineheight), paginate = TRUE, - round_type = obj_round_type(.get_first_element_of_object(x)), + round_type = obj_round_type(x), ...) { # Processing lists of tables or listings if (.is_list_of_tables_or_listings(x)) { @@ -574,7 +566,7 @@ export_as_pdf <- function(x, colwidths = NULL, fontspec = font_spec(font_family, font_size, lineheight), ttype_ok = FALSE, - round_type = obj_round_type(.get_first_element_of_object(x))) { + round_type = obj_round_type(x)) { ## this has to happen at the very beginning before the first use of fontspec ## which happens in the default value of colwidths. yay lazy evaluation... if (missing(font_size) && !missing(fontsize)) { diff --git a/R/pagination.R b/R/pagination.R index 0f0e6f027..a0a61543c 100644 --- a/R/pagination.R +++ b/R/pagination.R @@ -1201,7 +1201,7 @@ paginate_to_mpfs <- function(obj, # col_gap = 3, # this could be change in default - breaking change col_gap = 3, fontspec = font_spec(font_family, font_size, lineheight), - round_type = obj_round_type(.get_first_element_of_object(obj)), + round_type = obj_round_type(obj), verbose = FALSE) { newdev <- open_font_dev(fontspec) if (newdev) { diff --git a/inst/WORDLIST b/inst/WORDLIST index 29b31d724..d34016701 100644 --- a/inst/WORDLIST +++ b/inst/WORDLIST @@ -23,7 +23,6 @@ mandatorily monospace paginations pathing -peforms pre repo sas diff --git a/man/MatrixPrintForm.Rd b/man/MatrixPrintForm.Rd index 23df0b699..d47a84465 100644 --- a/man/MatrixPrintForm.Rd +++ b/man/MatrixPrintForm.Rd @@ -112,7 +112,8 @@ calculating string widths and heights, as returned by \code{\link[=font_spec]{fo \item{rep_cols}{(\code{numeric(1)})\cr number of columns to be repeated as context during horizontal pagination.} -\item{round_type}{(\code{"iec"}, \code{"iec_mod"} or \code{"sas"})\cr the type of rounding to perform. +\item{round_type}{(\code{string})\cr +The type of rounding to perform. Allowed values: (\code{"iec"}, \code{"iec_mod"} or \code{"sas"}) See \code{\link[=round_fmt]{round_fmt()}} for details.} } \value{ diff --git a/man/export_as_pdf.Rd b/man/export_as_pdf.Rd index ffce0d9f3..3eb58ba3b 100644 --- a/man/export_as_pdf.Rd +++ b/man/export_as_pdf.Rd @@ -31,7 +31,7 @@ export_as_pdf( colwidths = NULL, fontspec = font_spec(font_family, font_size, lineheight), ttype_ok = FALSE, - round_type = obj_round_type(.get_first_element_of_object(x)) + round_type = obj_round_type(x) ) } \arguments{ @@ -109,8 +109,10 @@ calculating string widths and heights, as returned by \code{\link[=font_spec]{fo allowed via \code{fontspec}. Defaults to \code{FALSE}. This parameter is primarily for internal testing and generally should not be set by end users.} -\item{round_type}{(\code{"iec"}, \code{"iec_mod"} or \code{"sas"})\cr the type of rounding to perform. iec, -the default, and iec_mod peforms rounding compliant with IEC 60559 (see notes in \code{\link[=round_fmt]{round_fmt()}}), while +\item{round_type}{(\code{string})\cr . +\cr The type of rounding to perform. Allowed values: (\code{"iec"}, \code{"iec_mod"} or \code{"sas"}) +\cr iec, the default, and iec_mod performs rounding compliant with IEC 60559 +(see notes in \code{\link[=round_fmt]{round_fmt()}}), while sas performs nearest-value rounding consistent with rounding within SAS.\cr In addition, the rounding of a negative number that rounds to zero will be presented as 0 (with the appropriate number of trailing zeros) for both \code{sas} and \code{iec_mod}, diff --git a/man/export_as_rtf.Rd b/man/export_as_rtf.Rd index 6408928af..249ec0035 100644 --- a/man/export_as_rtf.Rd +++ b/man/export_as_rtf.Rd @@ -18,7 +18,7 @@ export_as_rtf( lineheight = 1, fontspec = font_spec(font_family, font_size, lineheight), paginate = TRUE, - round_type = obj_round_type(.get_first_element_of_object(x)), + round_type = obj_round_type(x), ... ) } @@ -58,8 +58,10 @@ calculating string widths and heights, as returned by \code{\link[=font_spec]{fo \item{paginate}{(\code{flag})\cr whether pagination should be performed. Defaults to \code{TRUE} if page size is specified (including the default).} -\item{round_type}{(\code{"iec"}, \code{"iec_mod"} or \code{"sas"})\cr the type of rounding to perform. iec, -the default, and iec_mod peforms rounding compliant with IEC 60559 (see notes in \code{\link[=round_fmt]{round_fmt()}}), while +\item{round_type}{(\code{string})\cr . +\cr The type of rounding to perform. Allowed values: (\code{"iec"}, \code{"iec_mod"} or \code{"sas"}) +\cr iec, the default, and iec_mod performs rounding compliant with IEC 60559 +(see notes in \code{\link[=round_fmt]{round_fmt()}}), while sas performs nearest-value rounding consistent with rounding within SAS.\cr In addition, the rounding of a negative number that rounds to zero will be presented as 0 (with the appropriate number of trailing zeros) for both \code{sas} and \code{iec_mod}, diff --git a/man/export_as_txt.Rd b/man/export_as_txt.Rd index 0ad220971..f3f08d074 100644 --- a/man/export_as_txt.Rd +++ b/man/export_as_txt.Rd @@ -32,7 +32,7 @@ export_as_txt( page_num = default_page_number(), fontspec = font_spec(font_family, font_size, lineheight), col_gap = 3, - round_type = obj_round_type(.get_first_element_of_object(x)) + round_type = obj_round_type(x) ) } \arguments{ @@ -113,8 +113,10 @@ calculating string widths and heights, as returned by \code{\link[=font_spec]{fo \item{col_gap}{(\code{numeric(1)})\cr The number of spaces to be placed between columns in the rendered table (and assumed for horizontal pagination).} -\item{round_type}{(\code{"iec"}, \code{"iec_mod"} or \code{"sas"})\cr the type of rounding to perform. iec, -the default, and iec_mod peforms rounding compliant with IEC 60559 (see notes in \code{\link[=round_fmt]{round_fmt()}}), while +\item{round_type}{(\code{string})\cr . +\cr The type of rounding to perform. Allowed values: (\code{"iec"}, \code{"iec_mod"} or \code{"sas"}) +\cr iec, the default, and iec_mod performs rounding compliant with IEC 60559 +(see notes in \code{\link[=round_fmt]{round_fmt()}}), while sas performs nearest-value rounding consistent with rounding within SAS.\cr In addition, the rounding of a negative number that rounds to zero will be presented as 0 (with the appropriate number of trailing zeros) for both \code{sas} and \code{iec_mod}, diff --git a/man/format_value.Rd b/man/format_value.Rd index eb72fdd39..6a624d849 100644 --- a/man/format_value.Rd +++ b/man/format_value.Rd @@ -23,8 +23,10 @@ apply to \code{x}.} \item{na_str}{(\code{character})\cr character vector to display when the values of \code{x} are missing. If only one string is provided, it is applied for all missing values. Defaults to \code{"NA"}.} -\item{round_type}{(\code{"iec"}, \code{"iec_mod"} or \code{"sas"})\cr the type of rounding to perform. iec, -the default, and iec_mod peforms rounding compliant with IEC 60559 (see notes in \code{\link[=round_fmt]{round_fmt()}}), while +\item{round_type}{(\code{string})\cr . +\cr The type of rounding to perform. Allowed values: (\code{"iec"}, \code{"iec_mod"} or \code{"sas"}) +\cr iec, the default, and iec_mod performs rounding compliant with IEC 60559 +(see notes in \code{\link[=round_fmt]{round_fmt()}}), while sas performs nearest-value rounding consistent with rounding within SAS.\cr In addition, the rounding of a negative number that rounds to zero will be presented as 0 (with the appropriate number of trailing zeros) for both \code{sas} and \code{iec_mod}, diff --git a/man/make_row_df.Rd b/man/make_row_df.Rd index 9698783a8..14e3f06c0 100644 --- a/man/make_row_df.Rd +++ b/man/make_row_df.Rd @@ -73,8 +73,10 @@ calculating string widths and heights, as returned by \code{\link[=font_spec]{fo \item{col_gap}{(\code{numeric(1)})\cr the gap to be assumed between columns, in number of spaces with font specified by \code{fontspec}.} -\item{round_type}{(\code{"iec"}, \code{"iec_mod"} or \code{"sas"})\cr the type of rounding to perform. iec, -the default, and iec_mod peforms rounding compliant with IEC 60559 (see notes in \code{\link[=round_fmt]{round_fmt()}}), while +\item{round_type}{(\code{string})\cr . +\cr The type of rounding to perform. Allowed values: (\code{"iec"}, \code{"iec_mod"} or \code{"sas"}) +\cr iec, the default, and iec_mod performs rounding compliant with IEC 60559 +(see notes in \code{\link[=round_fmt]{round_fmt()}}), while sas performs nearest-value rounding consistent with rounding within SAS.\cr In addition, the rounding of a negative number that rounds to zero will be presented as 0 (with the appropriate number of trailing zeros) for both \code{sas} and \code{iec_mod}, diff --git a/man/matrix_form.Rd b/man/matrix_form.Rd index 08751810b..82bab814d 100644 --- a/man/matrix_form.Rd +++ b/man/matrix_form.Rd @@ -44,8 +44,10 @@ calculating string widths and heights, as returned by \code{\link[=font_spec]{fo \item{col_gap}{(\code{numeric(1)})\cr the gap to be assumed between columns, in number of spaces with font specified by \code{fontspec}.} -\item{round_type}{(\code{"iec"}, \code{"iec_mod"} or \code{"sas"})\cr the type of rounding to perform. iec, -the default, and iec_mod peforms rounding compliant with IEC 60559 (see notes in \code{\link[=round_fmt]{round_fmt()}}), while +\item{round_type}{(\code{string})\cr . +\cr The type of rounding to perform. Allowed values: (\code{"iec"}, \code{"iec_mod"} or \code{"sas"}) +\cr iec, the default, and iec_mod performs rounding compliant with IEC 60559 +(see notes in \code{\link[=round_fmt]{round_fmt()}}), while sas performs nearest-value rounding consistent with rounding within SAS.\cr In addition, the rounding of a negative number that rounds to zero will be presented as 0 (with the appropriate number of trailing zeros) for both \code{sas} and \code{iec_mod}, diff --git a/man/mpf_to_rtf.Rd b/man/mpf_to_rtf.Rd index c49e006be..1578945a0 100644 --- a/man/mpf_to_rtf.Rd +++ b/man/mpf_to_rtf.Rd @@ -50,7 +50,8 @@ if the family named is not monospaced. Defaults to \code{"Courier"}.} \item{fontspec}{(\code{font_spec})\cr a font_spec object specifying the font information to use for calculating string widths and heights, as returned by \code{\link[=font_spec]{font_spec()}}.} -\item{round_type}{(\code{"iec"}, \code{"iec_mod"} or \code{"sas"})\cr the type of rounding to perform. +\item{round_type}{(\code{string})\cr +The type of rounding to perform. Allowed values: (\code{"iec"}, \code{"iec_mod"} or \code{"sas"}) See \code{\link[=round_fmt]{round_fmt()}} for details.} \item{...}{additional parameters passed to individual methods.} diff --git a/man/obj_round_type.Rd b/man/obj_round_type.Rd index 708b9fcf1..f80e18263 100644 --- a/man/obj_round_type.Rd +++ b/man/obj_round_type.Rd @@ -3,14 +3,23 @@ \name{obj_round_type} \alias{obj_round_type} \alias{obj_round_type,MatrixPrintForm-method} +\alias{obj_round_type,list-method} \alias{obj_round_type<-} +\alias{obj_round_type<-,list-method} +\alias{obj_round_type<-,MatrixPrintForm-method} \title{Rounding Type} \usage{ obj_round_type(obj) \S4method{obj_round_type}{MatrixPrintForm}(obj) +\S4method{obj_round_type}{list}(obj) + obj_round_type(obj) <- value + +\S4method{obj_round_type}{list}(obj) <- value + +\S4method{obj_round_type}{MatrixPrintForm}(obj) <- value } \arguments{ \item{obj}{(\code{ANY})\cr a table-like object.} @@ -28,4 +37,7 @@ rounding type of the object. The setter method should only be created/used for pre-MatrixPrintForm objects, as resetting the rounding type after rounding occurs (which is during MPF creation) will not effect output when printing/exporting. + +round_type cannot not be updated on a \code{MatrixPrintForm} object +as rounding occurs during creation of MatrixPrintForm object } diff --git a/man/paginate_indices.Rd b/man/paginate_indices.Rd index 005e4dd07..28c57b293 100644 --- a/man/paginate_indices.Rd +++ b/man/paginate_indices.Rd @@ -57,7 +57,7 @@ paginate_to_mpfs( rep_cols = NULL, col_gap = 3, fontspec = font_spec(font_family, font_size, lineheight), - round_type = obj_round_type(.get_first_element_of_object(obj)), + round_type = obj_round_type(obj), verbose = FALSE ) @@ -150,8 +150,10 @@ in the rendered table (and assumed for horizontal pagination).} \item{fontspec}{(\code{font_spec})\cr a font_spec object specifying the font information to use for calculating string widths and heights, as returned by \code{\link[=font_spec]{font_spec()}}.} -\item{round_type}{(\code{"iec"}, \code{"iec_mod"} or \code{"sas"})\cr the type of rounding to perform. iec, -the default, and iec_mod peforms rounding compliant with IEC 60559 (see notes in \code{\link[=round_fmt]{round_fmt()}}), while +\item{round_type}{(\code{string})\cr . +\cr The type of rounding to perform. Allowed values: (\code{"iec"}, \code{"iec_mod"} or \code{"sas"}) +\cr iec, the default, and iec_mod performs rounding compliant with IEC 60559 +(see notes in \code{\link[=round_fmt]{round_fmt()}}), while sas performs nearest-value rounding consistent with rounding within SAS.\cr In addition, the rounding of a negative number that rounds to zero will be presented as 0 (with the appropriate number of trailing zeros) for both \code{sas} and \code{iec_mod}, diff --git a/man/propose_column_widths.Rd b/man/propose_column_widths.Rd index 9434dab0a..9ce633df2 100644 --- a/man/propose_column_widths.Rd +++ b/man/propose_column_widths.Rd @@ -20,8 +20,10 @@ a \code{MatrixPrintForm} object in favor of information there.} \item{fontspec}{(\code{font_spec})\cr a font_spec object specifying the font information to use for calculating string widths and heights, as returned by \code{\link[=font_spec]{font_spec()}}.} -\item{round_type}{(\code{"iec"}, \code{"iec_mod"} or \code{"sas"})\cr the type of rounding to perform. iec, -the default, and iec_mod peforms rounding compliant with IEC 60559 (see notes in \code{\link[=round_fmt]{round_fmt()}}), while +\item{round_type}{(\code{string})\cr . +\cr The type of rounding to perform. Allowed values: (\code{"iec"}, \code{"iec_mod"} or \code{"sas"}) +\cr iec, the default, and iec_mod performs rounding compliant with IEC 60559 +(see notes in \code{\link[=round_fmt]{round_fmt()}}), while sas performs nearest-value rounding consistent with rounding within SAS.\cr In addition, the rounding of a negative number that rounds to zero will be presented as 0 (with the appropriate number of trailing zeros) for both \code{sas} and \code{iec_mod}, diff --git a/man/round_fmt.Rd b/man/round_fmt.Rd index fcfa5c857..44257219f 100644 --- a/man/round_fmt.Rd +++ b/man/round_fmt.Rd @@ -22,8 +22,10 @@ character value with no rounding.} \item{na_str}{(\code{string})\cr the value to return if \code{x} is \code{NA}.} -\item{round_type}{(\code{"iec"}, \code{"iec_mod"} or \code{"sas"})\cr the type of rounding to perform. iec, -the default, and iec_mod peforms rounding compliant with IEC 60559 (see notes in \code{\link[=round_fmt]{round_fmt()}}), while +\item{round_type}{(\code{string})\cr . +\cr The type of rounding to perform. Allowed values: (\code{"iec"}, \code{"iec_mod"} or \code{"sas"}) +\cr iec, the default, and iec_mod performs rounding compliant with IEC 60559 +(see notes in \code{\link[=round_fmt]{round_fmt()}}), while sas performs nearest-value rounding consistent with rounding within SAS.\cr In addition, the rounding of a negative number that rounds to zero will be presented as 0 (with the appropriate number of trailing zeros) for both \code{sas} and \code{iec_mod}, diff --git a/man/test_matrix_form.Rd b/man/test_matrix_form.Rd index 2180ec2d3..640221a80 100644 --- a/man/test_matrix_form.Rd +++ b/man/test_matrix_form.Rd @@ -60,7 +60,8 @@ for more information.} Defaults to \code{0} for \code{basic_matrix_form} and \code{length(keycols)} for \code{basic_listing_mf}. Note repeating columns are separate from row labels if present.} -\item{round_type}{(\code{"iec"}, \code{"iec_mod"} or \code{"sas"})\cr the type of rounding to perform. +\item{round_type}{(\code{string})\cr +The type of rounding to perform. Allowed values: (\code{"iec"}, \code{"iec_mod"} or \code{"sas"}) See \code{\link[=round_fmt]{round_fmt()}} for details.} \item{keycols}{(\code{character})\cr a vector of \code{df} column names that are printed first and for which diff --git a/man/tostring.Rd b/man/tostring.Rd index 36ccb0517..930b5ff5e 100644 --- a/man/tostring.Rd +++ b/man/tostring.Rd @@ -48,7 +48,8 @@ calculating string widths and heights, as returned by \code{\link[=font_spec]{fo allowed via \code{fontspec}. Defaults to \code{FALSE}. This parameter is primarily for internal testing and generally should not be set by end users.} -\item{round_type}{(\code{"iec"}, \code{"iec_mod"} or \code{"sas"})\cr the type of rounding to perform. +\item{round_type}{(\code{string})\cr +The type of rounding to perform. Allowed values: (\code{"iec"}, \code{"iec_mod"} or \code{"sas"}) See \code{\link[=round_fmt]{round_fmt()}} for details.} } \value{ diff --git a/man/vert_pag_indices.Rd b/man/vert_pag_indices.Rd index a63879513..2de97c22c 100644 --- a/man/vert_pag_indices.Rd +++ b/man/vert_pag_indices.Rd @@ -34,8 +34,10 @@ calculating string widths and heights, as returned by \code{\link[=font_spec]{fo \item{nosplitin}{(\code{character})\cr list of names of subtables where page breaks are not allowed, regardless of other considerations. Defaults to none.} -\item{round_type}{(\code{"iec"}, \code{"iec_mod"} or \code{"sas"})\cr the type of rounding to perform. iec, -the default, and iec_mod peforms rounding compliant with IEC 60559 (see notes in \code{\link[=round_fmt]{round_fmt()}}), while +\item{round_type}{(\code{string})\cr . +\cr The type of rounding to perform. Allowed values: (\code{"iec"}, \code{"iec_mod"} or \code{"sas"}) +\cr iec, the default, and iec_mod performs rounding compliant with IEC 60559 +(see notes in \code{\link[=round_fmt]{round_fmt()}}), while sas performs nearest-value rounding consistent with rounding within SAS.\cr In addition, the rounding of a negative number that rounds to zero will be presented as 0 (with the appropriate number of trailing zeros) for both \code{sas} and \code{iec_mod}, diff --git a/tests/testthat/test-formatters.R b/tests/testthat/test-formatters.R index 84a463073..519122e44 100644 --- a/tests/testthat/test-formatters.R +++ b/tests/testthat/test-formatters.R @@ -1135,3 +1135,26 @@ test_that("Methods for obj_round_type", { expect_identical(df_iec, fmt_iec) expect_identical(df_sas, fmt_sas) }) + +test_that("Methods for obj_round_type on list object", { + inputdf <- mtcars + obj_format(inputdf$wt) <- "xx.xx" + + bmf <- basic_matrix_form(inputdf, round_type = "sas") + blmf <- basic_listing_mf(inputdf, keycols = c("vs", "gear"), round_type = "sas") + l_mf <- list(bmf, blmf) + + expect_identical(obj_round_type(l_mf), "sas") + + # test setter + # current object is list of MatrixPrintForm class, round_type cannot not be updated here + # as rounding occurs during creation of MatrixPrintForm object + l_mf_iec <- l_mf + expect_message(obj_round_type(l_mf_iec) <- "iec", + "'obj_round_type<-' should not be applied on class `MatrixPrintForm`") + expect_identical(obj_round_type(l_mf_iec), "sas") + + # test of setter for list of listing_obj will be included in rlistings instead + + +}) From df8be9e791058e586ad64f7af5969532b19cdb3d Mon Sep 17 00:00:00 2001 From: github-actions <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 5 Dec 2025 13:07:16 +0000 Subject: [PATCH 15/18] [skip style] [skip vbump] Restyle files --- tests/testthat/test-formatters.R | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/testthat/test-formatters.R b/tests/testthat/test-formatters.R index 519122e44..6f5e550b0 100644 --- a/tests/testthat/test-formatters.R +++ b/tests/testthat/test-formatters.R @@ -1150,11 +1150,11 @@ test_that("Methods for obj_round_type on list object", { # current object is list of MatrixPrintForm class, round_type cannot not be updated here # as rounding occurs during creation of MatrixPrintForm object l_mf_iec <- l_mf - expect_message(obj_round_type(l_mf_iec) <- "iec", - "'obj_round_type<-' should not be applied on class `MatrixPrintForm`") + expect_message( + obj_round_type(l_mf_iec) <- "iec", + "'obj_round_type<-' should not be applied on class `MatrixPrintForm`" + ) expect_identical(obj_round_type(l_mf_iec), "sas") # test of setter for list of listing_obj will be included in rlistings instead - - }) From 17979acc3ae7cc07aeb443f219e37818645d871a Mon Sep 17 00:00:00 2001 From: iaugusty Date: Fri, 5 Dec 2025 13:23:02 +0000 Subject: [PATCH 16/18] Trigger build or update From 0052689f1b9e830dcc9f25174e4dedc4ca5361b1 Mon Sep 17 00:00:00 2001 From: Gabe Becker Date: Fri, 5 Dec 2025 13:20:02 -0800 Subject: [PATCH 17/18] change message to error for MPF obj_round_type<- method. tweak NEWS.md --- NEWS.md | 11 ++++++----- R/generics.R | 6 ++++-- tests/testthat/test-formatters.R | 6 ++---- 3 files changed, 12 insertions(+), 11 deletions(-) diff --git a/NEWS.md b/NEWS.md index d23b1259c..1c524ea4e 100644 --- a/NEWS.md +++ b/NEWS.md @@ -2,11 +2,12 @@ * Optimized pagination sub-routines to avoid `matrix_form()` calls when not needed. * Optimized pagination sub-routine `.compress_mat()` to reduce computing time for long listings. * Fixed bug in pagination of listings caused by newlines in column values. -* Added `"default"` format label which will behave like `"xx"` but can - inherit formatting from parent structures in upstream code. -* Added new `round_type` method, `iec_mod`. Combined all allowed values for round_type into `valid_round_type` object. -* Modified the behavior for `round_type` = `sas` for negative value that rounds to zero, by not displaying the negative sign. -* New generic `getter` and `setter` for `round_type` (`obj_round_type` and `obj_round_type<-`). +* Added `"default"` format label which behaves like `"xx"` in `format_value` but indicates formatting behavior can be inherited from parent structures in upstream code. +* `round_type = "sas"` no longer displays a negative sign when negative values are rounded to zero. +* Added new `round_type`, `"iec_mod"`. Provides IEC style rounding but will not display negative sign when rounding to zero. +* New exported `valid_round_type` object for use as default value/with `match.arg` in upstream packages. +* New `obj_round_type` and `obj_round_type<-` generics for objects which carry around a round_type. +* Updated default round type value to retrieve the object's round type for all generics and relevant methods which accept round_type. ## formatters 0.5.11 * Fixed a bug in `mform_handle_newlines` that caused string matrix column names to be removed. This prevented paginated listing key column info from being repeated when vertically spanning multiple pages. diff --git a/R/generics.R b/R/generics.R index c05e903ff..9f6a70ba9 100644 --- a/R/generics.R +++ b/R/generics.R @@ -795,6 +795,8 @@ setMethod("obj_round_type<-", "list", function(obj, value) { #' @note round_type cannot not be updated on a `MatrixPrintForm` object #' as rounding occurs during creation of MatrixPrintForm object setMethod("obj_round_type<-", "MatrixPrintForm", function(obj, value) { - message("'obj_round_type<-' should not be applied on class `MatrixPrintForm`") - obj + stop( + "Cannot alter round type on a `MatrixPrintForm` object as it was ", + "constructed after rounding occurred." + ) }) diff --git a/tests/testthat/test-formatters.R b/tests/testthat/test-formatters.R index 6f5e550b0..8938098aa 100644 --- a/tests/testthat/test-formatters.R +++ b/tests/testthat/test-formatters.R @@ -1150,11 +1150,9 @@ test_that("Methods for obj_round_type on list object", { # current object is list of MatrixPrintForm class, round_type cannot not be updated here # as rounding occurs during creation of MatrixPrintForm object l_mf_iec <- l_mf - expect_message( + expect_error( obj_round_type(l_mf_iec) <- "iec", - "'obj_round_type<-' should not be applied on class `MatrixPrintForm`" + "Cannot alter round type on a `MatrixPrintForm` object" ) - expect_identical(obj_round_type(l_mf_iec), "sas") - # test of setter for list of listing_obj will be included in rlistings instead }) From 16b4e18047f44df9bcf7ba0ec3986beaae9f41c3 Mon Sep 17 00:00:00 2001 From: Gabe Becker Date: Fri, 5 Dec 2025 15:05:47 -0800 Subject: [PATCH 18/18] remove unnecessary calls to return to satisfy the lintr gods --- R/tostring.R | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/R/tostring.R b/R/tostring.R index bf46503a7..cea31f0e7 100644 --- a/R/tostring.R +++ b/R/tostring.R @@ -445,7 +445,7 @@ do_cell_fnotes_wrap <- function(mat, widths, max_width, tf_wrap, fontspec, expan } } # Final return - return(list("mfs" = mfs, "cell_widths_mat" = cell_widths_mat)) + list("mfs" = mfs, "cell_widths_mat" = cell_widths_mat) } ## take a character vector and return whether the value is @@ -902,7 +902,7 @@ setMethod("toString", "MatrixPrintForm", function(x, stop("max_width must be NULL, a numeric value, or \"auto\".") } } - return(max_width) + max_width } .do_inset <- function(x, inset) { @@ -1100,10 +1100,10 @@ wrap_string <- function(str, width, collapse = NULL, fontspec = font_spec()) { } if (!is.null(collapse)) { - return(paste0(ret, collapse = collapse)) + ret <- paste0(ret, collapse = collapse) } - return(ret) + ret } .go_stri_wrap <- function(str, w) {