Skip to content

Commit

Permalink
issue #409 replace NaN (#410)
Browse files Browse the repository at this point in the history
  • Loading branch information
vincentarelbundock authored Dec 27, 2024
1 parent 9e3e75a commit dcf4289
Show file tree
Hide file tree
Showing 4 changed files with 48 additions and 30 deletions.
19 changes: 11 additions & 8 deletions R/format_tt.R
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,9 @@
#' @param math Logical. If TRUE, wrap cell values in math mode `$..$`. This is useful for LaTeX output or with HTML MathJax `options(tinytable_html_mathjax=TRUE)`.
#' @param other A function to format columns of other types. Defaults to `as.character()`.
#' @param replace Logical, String or Named list of vectors
#' - TRUE: Replace `NA` by an empty string.
#' - FALSE: Print `NA` as the string "NA".
#' - String: Replace `NA` entries by the user-supplied string.
#' - TRUE: Replace `NA` and `NaN` by an empty string.
#' - FALSE: Print `NA` and `NaN` as strings.
#' - String: Replace `NA` and `NaN` entries by the user-supplied string.
#' - Named list: Replace matching elements of the vectors in the list by theirs names. Example:
#' - `list("-" = c(NA, NaN), "Tiny" = -Inf, "Massive" = Inf)`
#' @param escape Logical or "latex" or "html". If TRUE, escape special characters to display them as text in the format of the output of a `tt()` table.
Expand Down Expand Up @@ -94,7 +94,6 @@ format_tt <- function(x,
quarto = get_option("tinytable_format_quarto", default = FALSE),
fn = get_option("tinytable_format_fn", default = NULL),
sprintf = get_option("tinytable_format_sprintf", default = NULL)) {

assert_integerish(digits, len = 1, null.ok = TRUE)
assert_choice(num_fmt, c("significant", "significant_cell", "decimal", "scientific"))
assert_flag(num_zero)
Expand Down Expand Up @@ -227,11 +226,11 @@ format_tt_lazy <- function(x,
if (!is.null(bool) && is.logical(ori[i, col])) {
out[i, col] <- bool(ori[i, col, drop = TRUE])

# date
# date
} else if (!is.null(date) && inherits(ori[i, col], "Date")) {
out[i, col] <- format(ori[i, col, drop = TRUE], date)

# numeric
# numeric
} else if (!is.null(digits) && is.numeric(ori[i, col, drop = TRUE])) {
tmp <- format_numeric(ori[i, col],
num_suffix = num_suffix,
Expand All @@ -243,15 +242,19 @@ format_tt_lazy <- function(x,
)
if (!is.null(tmp)) out[i, col] <- tmp

# other
# other
} else if (is.function(other)) {
out[i, col] <- other(ori[i, col, drop = TRUE])
}
}

for (k in seq_along(replace)) {
idx <- ori[i, col, drop = TRUE] %in% replace[[k]]
out[i, col][idx] <- names(replace)[[k]]
if (identical(names(replace)[[k]], " ")) {
out[i, col][idx] <- ""
} else {
out[i, col][idx] <- names(replace)[[k]]
}
}
} # loop over columns

Expand Down
39 changes: 20 additions & 19 deletions R/sanity.R
Original file line number Diff line number Diff line change
Expand Up @@ -13,23 +13,23 @@ sanity_align <- function(align, i) {


sanitize_i <- function(i, x, pre_group_i = FALSE, lazy = TRUE) {
out <- seq_len(nrow(x))
if (is.null(i) && isTRUE(lazy)) {
out <- NA
attr(out, "null") <- TRUE
attr(out, "body") <- seq_len(nrow(x))
attr(out, "head") <- integer()
} else {
if (!is.null(i)) {
out <- i
} else if (inherits(x, "tinytable")) {
out <- seq_len(nrow(x@table_dataframe))
}
attr(out, "null") <- FALSE
attr(out, "body") <- out[out > 0]
attr(out, "head") <- out[out < 1]
out <- seq_len(nrow(x))
if (is.null(i) && isTRUE(lazy)) {
out <- NA
attr(out, "null") <- TRUE
attr(out, "body") <- seq_len(nrow(x))
attr(out, "head") <- integer()
} else {
if (!is.null(i)) {
out <- i
} else if (inherits(x, "tinytable")) {
out <- seq_len(nrow(x@table_dataframe))
}
return(out)
attr(out, "null") <- FALSE
attr(out, "body") <- out[out > 0]
attr(out, "head") <- out[out < 1]
}
return(out)
}
sanitize_i <- function(i, x, pre_group_i = FALSE, lazy = TRUE) {
if (is.character(i)) {
Expand Down Expand Up @@ -430,11 +430,12 @@ sanitize_notes <- function(notes) {

sanitize_replace <- function(replace) {
if (isTRUE(replace)) {
replace <- stats::setNames(list(NA), "")
replace <- stats::setNames(list(NA, NaN), c(" ", " "))
} else if (isFALSE(replace)) {
replace <- stats::setNames(list(NULL), "")
replace <- list(NULL)
} else if (isTRUE(check_string(replace))) {
replace <- stats::setNames(list(NA), replace)
if (identical(replace, "")) replace <- " "
replace <- stats::setNames(list(NA, NaN), c(replace, replace))
} else if (!is.list(replace) || is.null(names(replace))) {
stop("`replace` should be TRUE/FALSE, a single string, or a named list.", call. = FALSE)
}
Expand Down
14 changes: 14 additions & 0 deletions inst/tinytest/test-format_tt.R
Original file line number Diff line number Diff line change
Expand Up @@ -216,3 +216,17 @@ expect_true("16 GB" %in% tab$memory)
expect_true("99%" %in% tab$speed_benchmark)
expect_false("2024-01-15" %in% tab$date_lookup)


# Issue #409: both NA and NaN should be replaced
options(tinytable_format_replace = NULL)
tab <- data.frame(x = c(1, NA, NaN, Inf))
tab0 <- tt(tab) |> print("dataframe")
tab1 <- tt(tab) |>
format_tt() |>
print("dataframe")
tab2 <- tt(tab) |>
format_tt(replace = TRUE) |>
print("dataframe")
expect_equivalent(tab0$x, c("1", "NA", "NaN", "Inf"))
expect_equivalent(tab1$x, c("1", "NA", "NaN", "Inf"))
expect_equivalent(tab2$x, c("1", "", "", "Inf"))
6 changes: 3 additions & 3 deletions man/format_tt.Rd

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

0 comments on commit dcf4289

Please sign in to comment.