Open janekbennett opened 4 years ago
I fully support this feature addition and I would use it extensively.
This seems like a great feature request. Thanks for submitting it! This work can be done alongside other work that'll focus on alignment on characters.
Notes to self (Rich): the extra space allotted for the character (not present in rows 2 and beyond) needs to be accounted for and I think a scheme with (differing-width) space characters might be used here.
Hey @rich-iannone - I'm playing around with some of this, and came up with the following function. In general, this relies on monospace fonts and matching the "suffix" length with  
. This still requires passing raw HTML strings into gt::html()
, but it does work out nicely.
Part of the limitation I run into with using gt
's native text transform is that it will repeat the input vector, unless I supply a map()
function, which requires 2x text_transform()
calls (as seen in example 2).
library(gt)
library(tidyverse)
add_nbsp <- function(x, suffix = "", symbol, decimals = 1) {
suffix <- as.character(suffix)
symbol <- as.character(symbol)
if (symbol == "%" | suffix == "%") {
fmt_val <- round(x, digits = decimals) %>%
format(nsmall = decimals)
} else {
fmt_val <- x
}
length_nbsp <- rep(" ", nchar(suffix) + 1) %>%
paste0(collapse = "")
symb_add <- c(paste0(suffix, symbol), rep(length_nbsp, length(x) - 1))
glue::glue("{fmt_val}{symb_add}") %>%
purrr::map(gt::html)
}
head(gtcars) %>%
dplyr::mutate(
hp_pct = (hp / max(hp) * 100) %>% add_nbsp(suffix = "", symbol = "%"),
hp = add_nbsp(hp, "ft", "³")
) %>%
dplyr::select(mfr, model, year, trim, hp, hp_pct) %>%
gt() %>%
opt_table_font(font = google_font("Roboto Mono")) %>%
cols_align(align = "right", columns = vars(hp, hp_pct))
You can accomplish the same thing with 2x text_transform()
calls:
head(gtcars) %>%
mutate(hp_pct = (hp/max(hp) * 100)) %>%
dplyr::select(mfr, model, year, trim, hp, hp_pct) %>%
gt() %>%
opt_table_font(font = google_font("Roboto Mono")) %>%
cols_align(align = "right", columns = vars(hp, hp_pct)) %>%
text_transform(
locations = cells_body(vars(hp), rows = 1),
fn = function(x){ paste0(x, "ft³") %>% gt::html()}
) %>%
text_transform(
locations = cells_body(vars(hp), rows = 2:6),
fn = function(x){
nbsp_add <- rep(" ", 3) %>% paste0(collapse = "")
map(x, ~paste0(.x, nbsp_add) %>% gt::html())}
)
One more try at a more general "wrapper" function.
gtcars %>%
head() %>%
dplyr::select(mfr, year, bdy_style, mpg_h, hp) %>%
dplyr::mutate(mpg_h = rnorm(n = dplyr::n(), mean = 22, sd = 1)) %>%
gt() %>%
opt_table_font(font = google_font("Roboto Mono")) %>%
opt_table_lines() %>%
fmt_symbol_first(column = mfr, symbol = "$", suffix = " ", last_row_n = 6) %>%
fmt_symbol_first(column = year, symbol = NULL, suffix = "%", last_row_n = 6) %>%
fmt_symbol_first(column = mpg_h, symbol = "%", suffix = NULL, last_row_n = 6, decimals = 1) %>%
fmt_symbol_first(column = hp, symbol = "°", suffix = " F", last_row_n = 6, decimals = NULL)
For the format functions fmt_currency and fmt_percent, could there be an option to only put the appropriate symbol in the first row of the selection? I guess the option could be called
row_1_only
or something like that. Also, the values still have to be aligned as if the symbol were there in rows 2 and lower ( or the effect wouldn't be as good).Thank you!