Search code examples
htmlrdatatablesr-markdowndt

Display numeric column in exponent while keeping the filter function in HTML Rmarkdown DT datatable


I have the following data frame:

df <- data.frame(col1 = letters[1:10],
                 col2 = c(0, 0.52, 0.93, 2, 10, 51, 523, 52353, 623464, 12356833538))

I want to display the dataframe with the DT package in an HTML R markdown file, where col2 should be displayed as in the following graph but retaining it's numeric class:

exponent_col2

Because I want to retain the filtering function in DT. However, currently I'm using sub and formatC to force the column to be displayed in my desired way which makes it character and therefore lost the filtering slider in DT.

library(DT)
library(tidyverse)

df2 <- df %>% mutate(col2 = ifelse(col2 <= 10, 
                            formatC(col2, format = "f", digits = 2), 
                            sub("e\\+0?(\\d+)", " x 10<sup>\\1</sup>", formatC(col2, format = "e", digits = 2))))

datatable(df2, escape = F, rownames = FALSE,
  filter = list(position = "top", clear = F, plain = F))

This is the slider function that I would like to have:

DT_filter

Therefore I would like to know how to display the column with exponent while retaining the numeric property (or to retain the DT slide-filter function) in an HTML R markdown document.

I'm not sure if it's possible to achieve what I want, so any input would be greatly appreciated.


Solution

  • Changing the display while keeping the nature of the data is exactly the role of the column option render.

    library(DT)
    
    js <- JS(
      "function(data, type, row, meta) {",
      "  if(type === 'display' && data > 10) {",
      "    let sn = {};",
      "    [sn.coeff, sn.exponent] = data.toExponential().split('e')", 
      "      .map(x => Number(x));",
      "    data = sn.coeff.toFixed(2) + '&times;' + '10<sup>' + sn.exponent + '</sup>';",
      "  }",
      "  return data;",
      "}"
    )
    
    df <- data.frame(
      col1 = letters[1:10],
      col2 = c(0, 0.52, 0.93, 2, 10, 51, 523, 52353, 623464, 12356833538)
    )
    
    datatable(
      df, 
      options = list(
        columnDefs = list(
          list(targets = 2, render = js)
        )
      )
    )
    

    enter image description here