2
votes

I recently learned how to make awesome tables with kableExtra that included unicode symbols, so that they could work as interpretive tables for my plots.

library(dplyr)
library(kableExtra)

data.frame(
  Symbol = c("●", "●", "▲"),
  Description = c("bla bla bla", "bla bla bla", "bla bla bla"),
  Result = c("bla bla bla", "bla bla bla", "bla bla bla")
) %>%
  mutate(
    Symbol = cell_spec(Symbol, color = c("yellow", "pink", "pink"), escape = F)
  ) %>%
  kable(escape = F, align = c("c", "l", "l")) %>%
  kable_styling(full_width = F)

Results in a beautiful table that looks like so: enter image description here

I would now like to automatically render this into a PDF, but when I stick this exact code into an RMarkdown file set to knit to PDF, that led me into an hours long rabbit hole of trying to debug various latex errors associated with the unicode characters in the table, the number-signs in the color specifications causing issues, the footnotes, errors that state ! Misplaced \noalign. that I have yet to figure out the source of, etc.

I'll include the text of a full Rmd file at the end of this. I'm on a Mac if that makes a difference. Using BasicTex and tlmgr to install missing latex packages.

Is there either (1) a way to save my kableExtra table, which looks EXACTLY how I want it when rendered within RStudio, to a scalable PDF file, that doesn't involve RMarkdown? I played around with the write2pdf() function today but ran into unicode issues again. I also tried knitting it to html and converting it via a call to pandoc, but that removed most of the table formatting that I need.

Maybe I'm missing some easy solution out there, though... or (2) is anyone able to tell me what changes would get this Rmd code to render my chart correctly to PDF? The R code itself works fine. It's some kind of Latex issue I guess.

Thanks so much for any help.

---
title: ""
output:
  pdf_document:
    latex_engine: xelatex
---

```{r, echo=FALSE, results="asis"}
# TODOREQ: add "much" grammars for acute levels
# TODOREQ: change "levels of concern" to the respective guideline name.
# TODO: Change to groupby/summarize
# TODO: Factor out package loading and global variables into a single setup file

# Packages
suppressMessages(library(ggplot2))
suppressMessages(library(extrafont))
suppressMessages(library(kableExtra))
suppressMessages(library(dplyr))


  table_info <- data.frame(Symbol=c("&#9650", "&#9670", "&#2795"),
                       Name=c("Name1", "Name2", "Name3"),
                       Description=c("Description1", "Description2",
                                     "Description3"),
                       Results=c("Bad", "Good", "Bad"),
                       Color=c("#ffde71", "#394f38",
                               "#09a2dd"))

  ktable <- table_info %>%
    mutate(Symbol = cell_spec(Symbol, color = Color, escape = FALSE)) %>%
    select(-Color) %>%
    kable(escape = FALSE, align = c("c", "l", "l")) %>%
    kable_styling(full_width = FALSE)

  ktable


```
1
I don't have ghostscript installed on this machine so I can't show you how it works, but have you tried kable_as_image? More here: rdrr.io/cran/kableExtra/man/kable_as_image.htmlmysteRious
Thanks for the suggestion. Still playing around with this but it is seeming fruitful.bogenton

1 Answers

10
votes

There are a few problems.

  1. cell_spec is going to insert raw HTML code unless you ask it to insert LaTeX code. Use format = "latex" to do that.

  2. You need to specify the symbols in LaTeX code, not HTML markup. xelatex should support things like "\\symbol{9650}" for "&#9650", but I couldn't get anything to show up: maybe I don't have the fonts installed. Instead you can use AMS symbols; a filled circle is "$\\bullet$", an upward pointing filled triangle is "$\\blacktriangle$". I didn't look up your others, but if you're lucky, you'll find them in https://www.rpi.edu/dept/arc/training/latex/LaTeX_symbols.pdf.

  3. Regular kable tables are ugly in LaTeX; use the booktabs = TRUE option for nicer ones.

So this is what your ktable specification should look like:

  table_info <- data.frame(Symbol=c("$\\bullet$", "$\\bullet$", "$\\blacktriangle$"),
                       Name=c("Name1", "Name2", "Name3"),
                       Description=c("Description1", "Description2",
                                     "Description3"),
                       Results=c("Bad", "Good", "Bad"),
                       Color=c("#ffde71", "#394f38",
                               "#09a2dd"))

  ktable <- table_info %>%
    mutate(Symbol = cell_spec(Symbol, color = Color, format = "latex", 
                              escape = FALSE)) %>%
    select(-Color) %>%
    kable(escape = FALSE, align = c("c", "l", "l"), booktabs = TRUE) %>%
    kable_styling(full_width = FALSE)

  ktable