Search code examples
htmlmarkdownr-markdownflextable

Flextable : using superscript in the dataframe


This question was asked few times, but surprinsingly, no answer was given.

I want some numbers in my dataframe to appear in superscript. The functions compose and display are not suitable here since I don't know yet which values in my dataframe will appear in superscript (my tables are generated automatically).

I tried to use ^8^like for kable, $$10^-3$$, paste(expression(10^2)), "H\\textsubscript{123}", etc.

Nothing works !! Help ! I pull out my hair...

library(flextable)
bab = data.frame(c( "10\\textsubscript{-3}", 
paste(as.expression(10^-3)), '10%-3%', '10^-2^' ))
flextable(bab)

I am knitting from Rto html.


Solution

  • In HTML, you do superscripts using things like <sup>-3</sup>, and subscripts using <sub>-3</sub>. However, if you put these into a cell in your table, you'll see the full text displayed, it won't be interpreted as HTML, because flextable escapes the angle brackets.

    The kable() function has an argument escape = FALSE that can turn this off, but flextable doesn't: see https://github.com/davidgohel/flextable/issues/156. However, there's a hackish way to get around this limitation: replace the htmlEscape() function with a function that does nothing.

    For example,

    ```{r}
    library(flextable)
    env <- parent.env(loadNamespace("flextable")) # The imports
    unlockBinding("htmlEscape", env)
    assign("htmlEscape", function(text, attribute = FALSE) text, envir=env)
    lockBinding("htmlEscape", env)
    bab = data.frame(x = "10<sup>-3</sup>")
    flextable(bab)
    ``` 
    

    This will display the table as

    screenshot

    Be careful if you do this: there may be cases in your real tables where you really do want HTML escapes, and this code will disable that for the rest of the document. If you execute this code in an R session, it will disable escaping for the rest of the session.

    And if you were thinking of using a document like this in a package you submit to CRAN, forget it. You shouldn't be messing with bindings like this in code that you expect other people to use.

    Edited to add:

    In fact, there's a way to do this without the hack given above. It's described in this article: https://davidgohel.github.io/flextable/articles/display.html#sugar-functions-for-complex-formatting. The idea is to replace the entries that need superscripts or subscripts with calls to as_paragraph, as_sup, as_sub, etc.:

    ```{r}
    library(flextable)
    bab <- data.frame(x = "dummy")
    bab <- flextable(bab)
    bab <- compose(bab, part = "body", i = 1, j = 1,
             value = as_paragraph("10",
                                  as_sup("-3")))
    bab
    ```
    

    This is definitely safer than the method I gave.