2

I would like to used custom classes to display large number nicely with pandoc.tables (I am using pander), while knitting html or pdf.

I found a way to print nicely in the console thanks to this SO question.

In this example, printing x returns 6M 75M 743.5M 0.3M 4.3M:

print.million <- function(x, ...) {
    x <- paste0(round(x / 1e6, 1), "M")
    NextMethod(x, quote = FALSE, ...)
}
x <- c(6e+06, 75000400, 743450000, 340000, 4300000)
class(x) <- "million"
x

but this formatting disappears with pandoc.table: the original, unformatted values are displayed. I have tried custom formatting as well (answer of the SO question above):

format.million <- function(x,...)paste0(round(unclass(x) / 1e6, 1), "M")
as.data.frame.million <- base:::as.data.frame.factor

But without success.

Is there a way to make this work ? I am open to solutions other than pander, but kable does not seem compatible with my version of R (R version 3.2.3).

Community
  • 1
  • 1
paulwasit
  • 416
  • 2
  • 12

1 Answers1

0

The print.million method has no effect on pander, which is a different S3 method -- so you have to define pander.million here, eg:

> x <- c(6e+06, 75000400, 743450000, 340000, 4300000)
> pander(x)
_6000000_, _75000400_, _743450000_, _340000_ and _4300000_

> pander.million <- function(x, ...) pander(paste0(round(x / 1e6, 1), "M"))
> class(x) <- 'million'
> pander(x)
_6M_, _75M_, _743.5M_, _0.3M_ and _4.3M_

But to use this inside of a table with pandoc.table, I am not sure how you set the million class for your columns. Can you please come up with a reproducible example?

But eg you could pre-process your data.frame:

> x <- as.numeric(x)
> df <- data.frame(millions = x, billions = x * 1e3, text = 'foobar')
> numbers <- names(df)[sapply(df, is.numeric)]
> df[numbers] <- apply(df[, numbers, drop = FALSE], 1,
+                      function(x) paste0(round(x / 1e6, 1), "M"))
> pander(df, justify = 'right')

----------------------------
  millions   billions   text
---------- ---------- ------
        6M    743450M foobar

     6000M       0.3M foobar

       75M       340M foobar

  75000.4M       4.3M foobar

    743.5M      4300M foobar
----------------------------
daroczig
  • 28,004
  • 7
  • 90
  • 124
  • I am sorry I forgot to add an example. But it is actually quite simple: I tried `x` vs `pandoc.table(x)`. I would like to avoid preprocessing the data frame because in doing so I loose the ability to manipulate the data as they are now characters. – paulwasit Mar 08 '16 at 15:40
  • Or in your example, I would like to show `pandoc.table(c(sum(millions), sum(billions))` returned as the class 'millions'. Preprocessing the data frame means loosing the ability to manipulate the data as they are now characters. – paulwasit Mar 08 '16 at 15:46
  • @paulwasit I almost wrote that `pander` takes the final object to be reported as a markdown table, so there won't be any further data manipulation -- but having a second thought on that suggest that having a `formatter` option for numbers in the `pander` package would be indeed very useful. Can you please open a ticket on [GH](https://github.com/Rapporter/pander)? – daroczig Mar 12 '16 at 00:08
  • hello @daroczig, I have created a new issue in [GH](https://github.com/Rapporter/pander/issues/253). Thanks, and sorry for the delay :/ – paulwasit Mar 19 '16 at 18:52