rr-markdownr-flextable

How can I use superscripts in a flextable dataframe without compose and display?


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.

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

I am knitting from R to 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.