How to change fontface (bold/italics) for a cell in a kable table in rmarkdown?
Asked Answered
V

3

16

Is there a way to format a single cell in a table in rmarkdown? I am using kable to generate a table as follows:

library(knitr)
kable(data.frame(c('a','b','c'),c(1,2,3)))

I wish to bold "c" in the last row and also add a horizontal line at the end of the table. Any pointers?

Verdun answered 27/1, 2015 at 8:34 Comment(4)
Assuming you mean kable(data.frame(c('a','b','c'),c(1,2,3))) then is it possible to just do c('a', 'b', '**c**')? As for the horizontal line, I can't help you with kable (I'm not sure it's possible) but I think it's pretty straight forward to do with the package pander.Balcom
@DanielleMcCool Yeah I meant as strings. And the double star works. I will checkout pander. Thx.Verdun
@DanielleMcCool Is it possible to have multicolumns in a single column using kable/pandoc?Verdun
@Avinash, Stack Overflow is designed for asking one question at a time. If you have another question, please submit a new one.Delaine
P
4

Highlighting cells, rows or columns with pander is pretty straightforward:

> df <- data.frame(c('a','b','c'),c(1,2,3))
> emphasize.strong.cells(which(df == 3, arr.ind = TRUE))
> pander(df)

-------------------------------
 c..a....b....c..   c.1..2..3. 
------------------ ------------
        a               1      

        b               2      

        c             **3**    
-------------------------------

But adding horizontal line to the table is out of the scope of markdown table specifications.

Phthalein answered 27/1, 2015 at 15:26 Comment(0)
L
13

Just generalising the question to include other font faces. Pandoc offers other ways to easily reformat text, and as explained in the RMarkdown Cheatsheet:

  • italics can be achieved using *italics*
  • bold can be achieved using **bold**
  • strikethrough can be achieved using ~~strikethrough~~

This output will support the various output methods, including PDF, html and word:

Here is a basic example:

---
output: pdf_document: default
---

```{r}
knitr::kable(data.frame(char = c('*a*','**b**','~~c~~'),
                 num = c(1,2,3)))
```

enter image description here

Applying formatting with a function

To make it easier to select cells to reformat, I have put together the following function format_cells.

format_cells <- function(df, rows ,cols, value = c("italics", "bold", "strikethrough")){

  # select the correct markup
  # one * for italics, two ** for bold
  map <- setNames(c("*", "**", "~~"), c("italics", "bold", "strikethrough"))
  markup <- map[value]  

  for (r in rows){
    for(c in cols){

      # Make sure values are not factors
      df[[c]] <- as.character( df[[c]])

      # Update formatting
      df[r, c] <- paste0(markup, df[r, c], markup)
    }
  }

  return(df)
}

It allows the user to select the cell row and columns which need to be reformatted and select the styling to apply. Multiple cells can be selected at the same time if several values in a row/column need to be reformatted. Here is an example:

library(tidyverse)

df <- data.frame(char = c('a','b','c'),
                 num = c(1,2,3))

df %>%
  format_cells(1, 1, "italics") %>%
  format_cells(2, 2, "bold") %>%
  format_cells(3, 1:2, "strikethrough") %>%
  knitr::kable()

Further Reading: the kableExtra package has been written to offer a lot of extra controls of styling of tables. However, the advice is different for the different types of output, and therefore there are different approaches for HTML and LaTeX

Lineolate answered 4/4, 2018 at 17:6 Comment(1)
How would your simple example of text formatting work with kableExtra c("*", "*", "~~")? Using kableExtra does not recognise these formatting options. It allows to format entire cells in a table via cell_spec(), but not part of it?Tallyho
S
10

This also works: the first argument is row number, so you can bold rows programmatically or columns using column_spec.

library(kableExtra)

library(tidyverse)


kable(data.frame(letter =c('a','b','c'),number =c(1,2,3)))%>%
  kable_styling()%>%
  row_spec(3,bold=T,hline_after = T)
Staffordshire answered 16/12, 2019 at 23:33 Comment(0)
P
4

Highlighting cells, rows or columns with pander is pretty straightforward:

> df <- data.frame(c('a','b','c'),c(1,2,3))
> emphasize.strong.cells(which(df == 3, arr.ind = TRUE))
> pander(df)

-------------------------------
 c..a....b....c..   c.1..2..3. 
------------------ ------------
        a               1      

        b               2      

        c             **3**    
-------------------------------

But adding horizontal line to the table is out of the scope of markdown table specifications.

Phthalein answered 27/1, 2015 at 15:26 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.