5

I am attempting to output a latex table using r markdown, kable, and kableExtra. I needed to use conditional logic to add colors to my table with cell_spec. But with the pdf output, it shows latex code as follows;

pdf output with latex code

If I add escape = false in kable(), it gives me the following error,

! Missing $ inserted. $ l.142 sepal_ length & sepal_width & petal_length & petal_width & Species\ Here is how much of TeX's memory you used: 14185 strings out of 492970 208670 string characters out of 3125261 323511 words of memory out of 3000000 17834 multiletter control sequences out of 15000+200000 23725 words of font info for 40 fonts, out of 3000000 for 9000 1141 hyphenation exceptions out of 8191 41i,9n,38p,1027b,272s stack positions out of 5000i,500n,10000p,200000b,50000s

I'm new to rmarkdown and , please help me to solve the issue. Thank you.

This is my rmd file code:

---
title: "Iris Data Table"
output: pdf_document
header-includes: \usepackage [table]{xcolor}
geometry: margin = 1cm
params:
  n: NA
  datafile: "//ad.monash.edu/home/User076/vbed0001/Documents/IRIS.csv" #always set the absolute full path
---

```{r, echo=FALSE, message=FALSE}

d <- read.csv(params$datafile, header = TRUE, sep = ",")

# this uses to remove the warning messages from the pdf file
library(memisc, warn.conflicts = FALSE, quietly=TRUE)

# the package order is important, always kableExtra at the top
#options(kableExtra.latex.load_packages = FALSE)
library(kableExtra)
library(magrittr)
library(formattable)
library(dplyr)
library(knitr) 
library(devtools)


options(knitr.table.format = "latex")

if(params$n == "set"){
dtset <- d %>% filter(Species == "setosa")

dtset <- d %>% filter(Species == "setosa")

dtset %>%
 mutate(
   sepal_length = cell_spec(sepal_length,format = "latex",background = (ifelse(sepal_length>4.5,"#D3D3D3","#ff0000")))

 )%>%
 kable(format = "latex",caption = "Setosa Table")%>%
   kable_styling(position = "center",bootstrap_options = "bordered")


}


```
Martin Schmelzer
  • 23,283
  • 6
  • 73
  • 98
Vish
  • 53
  • 3

3 Answers3

8

This error is a result of having underscores "_" in your dataframe. In this case, the column names contain underscores. In TeX this symbol is used to set subscripts in math environments. This is why it has to be escaped (\_) when used in normal text. Remove, escape or replace the underscores with e.g.

names(data) <- gsub("_", "", names(data))    # remove
names(data) <- gsub("_", "\\_", names(data)) # escape
names(data) <- gsub("_", " ", names(data))   # replace with space
Martin Schmelzer
  • 23,283
  • 6
  • 73
  • 98
  • 1
    One thing I did is, using `dplyr::rename_all` I defined `esc.us <- function(nm) { gsub("_", "\\\\_", nm) }` then piped the data table as follows: `data %>% rename_all(esc.us)`. There may be a better way, but it seems to work. – steveb Feb 24 '21 at 18:16
  • 1
    @steveb, the newer `tidyverse`/`dplyr` approach would be to use `replace_with` – climatestudent May 09 '23 at 11:01
  • @climatestudent thanks for adding that update! I will have a look as this seems like it could be a better approach. – steveb May 12 '23 at 16:36
3

In my case, I need to remove the underscore from the chunk name.

For example, this works:

```{r summaryTableBaseline, results='asis', echo=FALSE}
summaryTableBaseline %>%
    kable(col.names = c("Docker Image", "Min", "Mean", "Median", "Max"),
          caption = "Baseline Benchmark") %>%
    kable_styling()
```

But this does not work:

```{r summary_Table_Baseline, results='asis', echo=FALSE}
summaryTableBaseline %>%
    kable(col.names = c("Docker Image", "Min", "Mean", "Median", "Max"),
          caption = "Baseline Benchmark") %>%
    kable_styling()
```
ismailsunni
  • 1,458
  • 1
  • 24
  • 32
1

General solution for underscores anywhere in the data

Building on the good comment by @steveb, I generalized the solution so it can not only work on column names (as replace_all does).

data %>% map_df(~ gsub("_", "\\_", .x))

Explanation:

  1. The purrr::map processes every table cell for that.
  2. The purrr::map_df puts the result into a dataframe
  3. As argument, purrr::map accepts a function for which the purrr shortcut is ~ and the function argment is .x (for every element)
Agile Bean
  • 6,437
  • 1
  • 45
  • 53