I have column in my DT output (in Shiny) that has a numeric value whose units depend on another column. Some values are percentages, some are currency, and some are plain numbers.
For example, I would like to turn this input...
DefaultFormat | Value |
---|---|
PCT | 12345.67 |
DOLLAR | 12345.67 |
NUMBER | 12345.67 |
...into this DT output:
DefaultFormat | Value |
---|---|
PCT | 123.45% |
DOLLAR | $12,345 |
NUMBER | 12,345.67 |
The formatCurrency()
, formatPercentage()
and formatRound()
functions do what I need for each of these respective formats but they affect the entire column instead specific cells. On the other hand formatStyle()
can target specific cells in a column based on another column but I can't figure out a way to have it change the contents rather than the styles.
Furthermore, I tried setting the class using formatStyle()
in the hopes that in the .css file I could then target, e.g. .pctclass:after
and .currencyclass:before
but it ignores the class attribute.
What is a good way to get the conditional behavior of formatStyle()
but for numbers, percentages, and currencies?
CodePudding user response:
(This is not DT
-specific, it wasn't clear if that was a requirement.)
You can group or split and assign:
library(dplyr)
set.seed(2)
dat <- data.frame(fmt = sample(c("PCT","DOLLAR","NUMBER"), 10, replace = TRUE), value = round(runif(10, 10, 9999), 2))
dat %>%
group_by(fmt) %>%
mutate(value2 = switch(fmt[1],
PCT=scales::percent(value),
DOLLAR=scales::dollar(value),
NUMBER=scales::percent(value),
as.character(value))
)
# # A tibble: 10 x 3
# # Groups: fmt [3]
# fmt value value2
# <chr> <dbl> <chr>
# 1 PCT 1816. 181 621%
# 2 NUMBER 4058. 405 836%
# 3 DOLLAR 8536. $8,536.10
# 4 DOLLAR 9763. $9,763.24
# 5 PCT 2266. 226 577%
# 6 PCT 4453. 445 320%
# 7 PCT 759. 75 897%
# 8 PCT 6622. 662 171%
# 9 PCT 3881. 388 123%
# 10 DOLLAR 8370. $8,369.69
An alternative would be to use case_when
and it would come up with very similar results, but it will be working one string at a time; this method calls the format function once per group, perhaps a bit more efficient. (Over to you if that's necessary.)
CodePudding user response: