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:

