Search code examples
latexr-markdownkablekableextra

Error compiling kableExtra Table to PDF with knitr in RMarkdown


At the suggestion of another user, I created some sharable data to reproduce this issue. Please note that it only occurs when compiling a PDF from RMarkdown.

```
---
title: "Test_data"
output: pdf_document
geometry: "left=.5in,right=.5in,top=.75in,bottom=.75in"
graphics: yes
keep_tex: true
header-includes:
  - \usepackage{titling}
  # - \usepackage{nopageno}
  - \setlength{\droptitle}{15em}
  - \usepackage{caption}
  - \captionsetup{font=Large}

---
\newpage
```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = FALSE, warning = FALSE, message = FALSE)

library(dplyr)
library(kableExtra)
library(forcats)


dfcol1 <- rownames(mtcars)
dfcol2 <- c("ABC XYZ1 GAMUT",  "ABC XYZ1 O&M", "USU: IMIT Requirement", "OFFICE OF KJHDH RESEARCH (PPP)\r\n\r\nData Analytics Business Intelligence, Data Science Support", "Test DATA Support", "ABCD Classified Requirement (XYZ Connection)", "Customer Experience (AB) Admin Services", "New ABC Contract for Salesforce/TEST11soft Licenses ABC Transfer Region X", "AFLDP (ABC 123! Leadership Dev Program) PM", "AF MyVECTOR", "Talent Marketplace", "ABCDE / VWXYZ", "Online Education & Training Management", "AB 1234567890", "AB Automated Education Mgmt Sys (ABCDEF)", "ABCD Cyberpunk12345 Recompete", "Service Now Enterprise Solutions", "ABC ABCD AB Office of Budget", "ABC Catalyst (ABCD) A&B Requirement", "ABCDE - A1 ABC Projects to A12 for Regional Work (Potential ABCD 1 A23 Facilitation)", "ABCDE Help Desk Recompete (ABCD12345456789 )", "ABCXYZ Facility Related Control Systems  (1234), and Advanced Metering Infrastructure (ABC) System Upgrades", "ABCDE Recompete Package", "Software Development ABC \r\n(Digital ABDERTHKDOUG Phase 2 task order)", "ABC Program office X support (abcdefghtihf)", "Network Management Support (abcdefghjikl)", "Domain X - Bridges", "Domain 3 ABC - B-TEST ABC AB 3 DAY 181 XX", "Domain 4 - Abcde - B-TEST ABC AB 4 DAY 181 XX", "Domain 3 ABC - B-TEST ABC AB 3 DAY 181 XX", "Domain 4 - Abcde - B-TEST ABC AB 4 DAY 181 XX", "Domain 3 ABC - B-TEST ABC AB 3 DAY 181 XX")

dfcolnames <- c("Names", "Problem Column")

df <- as.data.frame(cbind(dfcol1, dfcol2))
colnames(df) <- dfcolnames

df1 <- df%>%
  left_join(mtcars%>%
              mutate(Names = rownames(mtcars),
                     gear = as.character(gear)))%>%
  select("mpg", "Problem Column", "disp", "gear", "Names", "hp", "drat")
```

\renewcommand{\arraystretch}{1.75}
\captionsetup[table]{labelformat=empty, font={bf, Large}}
```{r, echo=FALSE, results='asis'}
print(
  kable(df1, escape = T, align = 'lccccc', longtable = TRUE,
        caption = "Problem Table")%>%
    pack_rows(index = table(fct_inorder(df1$gear)), escape = F, latex_align = 'c')%>%
    pack_rows(index = table(fct_inorder(df1$Names)))%>%#, escape = F, latex_align = 'c')%>%
    kable_styling(latex_options = c("HOLD_position", "repeat_header", "asis"), font_size = 8)%>%
    column_spec(1, bold = F, width_min = ".5in", width = "1in")%>%
    column_spec(2, bold = F, width_min = "1.5in", width = "2.5in")%>%
    column_spec(3, bold = F, width_min = ".5in", width = ".7in")%>%
    column_spec(4:6, bold = F, width_min = "0.35in", width = "0.75in")%>%
    column_spec(7, bold = F, width_min = "0.2in", width = "0.25in")
)
cat("\n")

```
```
```

Note that the document can now be compiled by moving "21.4 & OFFICE OF KJHDH RESEARCH (PPP)" from line 121 of the tex file to immediately after the second close bracket on line 123 AND "13.3 & Software Development ABC " from line 205 to immediately after the second close bracket on line 208.

Original Post: I have an RMarkdown script which was successfully compiling a PDF report. Then I changed one of the columns to something else and the following error was thrown:

```
! Misplaced \omit.
\multispan ->\omit 
                   \@multispan 
l.391 \multicolumn{7}{c}{\textbf{<redacted name1>}}
                                                  \\ 
```

In the original code, the following code block is the culprit. Commenting it out allows the document to compile. The column in question is the second one. If I manually mutate that column in the data prep block, the document compiles. Of course, that can only be done in testing as we need the information in that column. Please note the prep cannot be shown due to confidentiality concerns, but mutate('col2 name' = "AAAAA") works fine, but mutate('col2 name' = if_else(condition, "New Text", 'col2 name')) does not despite several conditions and replacements.

```
print(
  kable(df_inproc_COa, escape = T, align = 'lccccc', longtable = TRUE, 
        caption = "Events Beginning within 2 months")%>%
    # header_separate(sep = "[^[:alnum:]]+")%>%
    pack_rows(index = table(fct_inorder(df_inproc_CO$`CO Branch`)), escape = F, latex_align = 'c')%>%
    pack_rows(index = table(fct_inorder(df_inproc_CO$`CO`)))%>%#, escape = F, latex_align = 'c')%>%
    kable_styling(latex_options = c("HOLD_position", "repeat_header", "asis"), font_size = 8)%>%
    column_spec(1, bold = F, width_min = ".5in", width = "1in")%>%
    column_spec(2, bold = F, width_min = "1.5in", width = "2.5in")%>%
    column_spec(3, bold = F, width_min = ".5in", width = ".7in")%>%
    column_spec(4:6, bold = F, width_min = "0.35in", width = "0.75in")%>%
    column_spec(7, bold = F, width_min = "0.2in", width = "0.25in")%>%
    row_spec(which(df_inproc_COa$`Days Left` <=0), bold = T, background = "red")
)
```

I have tried adjusting the column widths to no avail, so I read through the Tex Log file and began working with the Tex document generated from RMarkdown (keep_tex = TRUE). Therein, I found a solution. Changing this

<readacted id1> & <redacted title part 1>

\multicolumn{7}{c}{\textbf{<redacted name1>}}\\
\hline
\multicolumn{7}{l}{\textbf{<redacted name2>}}\\
\hline
\hspace{1em}\hspace{1em}<redacted title part 2> & 02/23/2024 & 12/14/2022 & 12/13/2022 & 12/14/2022 & 15 days\\

to this

\multicolumn{7}{c}{\textbf{<redacted name1>}}\\
\hline
\multicolumn{7}{l}{\textbf{<redacted name2>}}\\
\hline
\hspace{1em}\hspace{1em}<readacted id1> & <redacted title part 1><redacted title part 2> & 02/23/2024 & 12/14/2022 & 12/13/2022 & 12/14/2022 & 15 days\\

allows the Tex document to compile. Note that I simply moved <readacted id1> & <redacted title part 1> to immediately in front of <redacted title part 2>.

I would really like to find a way to solve this on the RMarkdown side so the document can compile directly. What's causing the tex code to write so incorrectly and how can I fix it? Please note that choosing a different column for the second position also works, but I need to include that information. Thank you in advance and I apologize once again for the lack of a reproducible example.


Solution

  • You have control characters in column 2 of your sample data, e.g. df1[4,2] contains this string:

    ## [1] "OFFICE OF KJHDH RESEARCH (PPP)\r\n\r\nData Analytics Business Intelligence, Data Science Support"
    

    Get rid of those control characters and things should work. In your example, I could do it like this:

    df1[,2] <- gsub("[[:cntrl:]]", "", df1[,2])
    

    This line should go at the end of the first code chunk.

    Your real dataset might have control characters in other columns.