11

Given a data.frame A, how can I use subscripted rows and columns names? Eventually I want produce a table through kable() in rmarkdown (output: word document).

A <- data.frame(round(replicate(3, runif(2)),2))
rownames(A) <- c("Hola123", "Hola234")
A

          X1   X2   X3
Hola123 0.47 0.55 0.66
Hola234 0.89 0.45 0.20

How could I make all numbers from row and column names subscripted when creating a table through kable(A)?

I have tried:

rownames(A) <- c(expression(Hola["123"]), expression(Hola["234"]))
names(A) <- c(expression(X["1"]), expression(X["2"]), expression(X["3"]))

But it does not appear subscripted when creating the table through kable() in the .rmd file.

starball
  • 20,030
  • 7
  • 43
  • 238
AJMA
  • 1,134
  • 2
  • 13
  • 28

3 Answers3

12

To add subscripts in a rmarkdown document, you can embed your text between two tilde: text~sub~. When using function kable, any text in the table is recognized as markdown syntax. So that your rmarkdown code should be:

```{r}
A <- data.frame(round(replicate(3, runif(2)),2))
rownames(A) <- c("Hola~123~", "Hola~234~")
names(A) <- c("X~1~", "X~2~", "X~3~")
knitr::kable(A)
```
Sébastien Rochette
  • 6,536
  • 2
  • 22
  • 43
  • 9
    This took me some time to figure out, so just in case someone wants to repeat this for a ``pdf`` output with ``latex`` tables: You cannot use ``markdown`` syntax in ``latex`` tables! What you would have to do is to add ``escape = F`` to ``kable()`` and then use ``latex`` syntax like ``\\texsubscript{ }`` (note the additional ``/``), example: ``Hola\\texsubscript{123}`` – bamphe Jun 21 '18 at 09:13
  • 5
    Like Rubem pointed out below, this is misspelled: use `\\textsubscript{123}`. This is just a note to future readers who, like me, read `tex`, go "Ah, that makes sense for a LaTeX command I guess," and stop reading further. – DuckPyjamas Mar 24 '19 at 22:10
  • Thanks for the useful answer. Btw superscript is "^text^". – Clem Snide May 12 '22 at 13:10
6

Just one note about bamphe's response is that the correct code is misspelled. It should be \\textsubscript{}. It is missing the second "t".

And completing the answer, you might choose to use the arguments row.names and col.names inside kable, in this way:

A <- data.frame(round(replicate(3, runif(2)),2))

rownames(A) <- c("Hola\\textsubscript{123}", "Hola\\textsubscript{234}")

knitr::kable(A,
             row.names = T,
             col.names = c("X\\textsubscript{1}", "X\\textsubscript{2}", "X\\textsubscript{3}"),
             escape = F)
rdornas
  • 630
  • 7
  • 15
  • 1
    Beware that data and names inside the table that contain special characters ( & % $ # _ { } ~ ^ \`) need to be escaped with \\ also. If you're doing the escaping with regex then you also need to escape the slashes in regex, so you end up with code like `str_replace_all(str, "_", "\\\\_")`. – DuckPyjamas Mar 24 '19 at 22:07
2

I, too, was looking for a method that would allow for subscript and superscript in both html and pdf formats in markdown tables with kable. After a bit of searching, I finally found the text reference method explained here by @yihui-xie : bookdownguide

(ref:foo) H~2~O where foo is the reference and H~2~O the text.

My code example shows how the text reference can be used. Make sure to follow the cardinal rules:

  1. The reference needs to be unique throughout the document
  2. The reference should not have a white space following the "to be inserted stuff"
  3. The reference needs to be in its own paragraph and have an empty line both above and below it

Note that only the referenced "foo" and "fo" will give the subscripts while the ~[]~ method will only work in html but not pdf.


(ref:foo) CO~2~/CO~2~

(ref:fo) CO~2~


```{r chunk-to-show-the-text-reference-method, echo = FALSE }
library(dplyr)
library(knitr)
library(kableExtra)

# Make lists
dtmin_name <- c("ref/ref","refrigerant/CO2","(ref:foo)",paste0("ground/","(ref:fo)"),"ground/water","air/refrigerant","water/refrigerant","water/CO2")
temp_diff <- c( 2.3, 1.4, 0.8, 6.8, 14, 6, 4, 3.46)

# Make dataframe and column names
dtmin_df <- data.frame(dtmin_name,temp_diff, stringsAsFactors = FALSE)
colnames <- data.frame("Interface Type ", "dT~min~ Interval [K]", stringsAsFactors = FALSE)
colnames(dtmin_df) <- colnames

# Make Table
kable(dtmin_df, caption = "Typical dT~min~ Temperature Intervals", booktabs = TRUE, format.args = list(big.mark = ",")) %>%
  kable_styling(bootstrap_options = c("striped", "hover"),latex_options = c("striped","scale_down"))```
Martin
  • 401
  • 6
  • 15