I'm looking at formatting a table using scales::dollar
within mutate_all
.
The desired results can be obtained with use of the sapply
:
>> sapply(mtcars, scales::dollar)
mpg cyl disp hp drat wt qsec vs am gear carb
[1,] "$21.00" "$6" "$160.00" "$110" "$3.90" "$2.62" "$16.46" "$0" "$1" "$4" "$4"
[2,] "$21.00" "$6" "$160.00" "$110" "$3.90" "$2.88" "$17.02" "$0" "$1" "$4" "$4"
[3,] "$22.80" "$4" "$108.00" "$93" "$3.85" "$2.32" "$18.61" "$1" "$1" "$4" "$1"
[4,] "$21.40" "$6" "$258.00" "$110" "$3.08" "$3.22" "$19.44" "$1" "$0" "$3" "$1"
Attempt to achieve the same results via dplyr
pipeline and scales::dollar
:
mtcars %>% mutate_all(funs(scales::dollar(.)))
fails:
Error in vapply(dots[missing_names], function(x) make_name(x$expr), character(1)) :
values must be length 1,
but FUN(X[[1]]) result is length 3
A primitive workaround can be attempted:
mtcars %>% mutate_each(funs(as.character(paste0("$", .))))
results:
>> mtcars %>% mutate_each(funs(as.character(paste0("$", .))))
mpg cyl disp hp drat wt qsec vs am gear carb
1 $21 $6 $160 $110 $3.9 $2.62 $16.46 $0 $1 $4 $4
2 $21 $6 $160 $110 $3.9 $2.875 $17.02 $0 $1 $4 $4
3 $22.8 $4 $108 $93 $3.85 $2.32 $18.61 $1 $1 $4 $1
Following a similar discussion, the approach could be easily developed further to create the desired currency format, but this is not the point.
Why scales::dollar(.)
fails when applied within mutate_all
(or mutate_each
)? When
applied to vector elements it works as expected, shouldn't this behaviour be replicated along observations available in a column when passed within mutate_all
/ mutate_each
:
>> scales::dollar(c(1, 1e4))
[1] "$1" "$10,000"
We need to wrap with as.character
as it seems to be a bug when we use package::function
in the funs
. It is documented here
mtcars %>%
mutate_each(funs(as.character(scales::dollar(.))))
Besides, the function mutate_each
is getting deprecated based on the blog link @Frank shared, so we can use mutate_at
mtcars %>%
mutate_at(names(.), funs(as.character(scales::dollar(.))))
The remedy would be to load the package and then call without the ::
library(scales)
mtcars %>%
mutate_at(names(.), funs(dollar(.)))
Or
mtcars %>%
mutate_at(names(.), dollar)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With