quartopdflatexkableextra

kable_styling overrides linesep = "" and adds space every 5 rows


This is partially related to this post, but for some reason I seem not to be able to fix my issue. In Quarto, when I create a table using kable with booktabs = TRUE and linesep = "" I get the expected results (no extra space every 5 rows):

---
title: "Test"
format: pdf
---

```{r}
library(kableExtra)
dat <- data.frame(v1 = letters[1:10], v2 = 1:10)
kable(dat, booktabs = TRUE, linesep = "")
```

No kable_styling, expected results.

If I use kable_styling() to get a striped table, an extra space is added after the fifth row:

---
title: "Test"
format: pdf
---

```{r}
library(kableExtra)
dat <- data.frame(v1 = letters[1:10], v2 = 1:10)
kable(dat, booktable = TRUE, linesep = "") |> 
  kable_styling(latex_options = "striped")
```

With kable_styling an extra space is added even with linesep = ""

I get the extra space when I use kable_styling() even without booktabs = TRUE:

---
title: "Test"
format: pdf
---

```{r}
library(kableExtra)
dat <- data.frame(v1 = letters[1:10], v2 = 1:10)
kable(dat) |> 
  kable_styling()
```

Extra space even without booktabs = TRUE

To my understanding this is not the expected behavior of kable_styling(), is there something I am missing?


Solution

  • You are not missing something, the table source code generation works differently here and ignores the provided linesep argument (it's more or less a kableExtra topic, see below for an explanation of the issue).

    However, you could include a \setlength{\defaultaddspace}{0pt} in the header, this makes the spaces go away (see the booktabs documentation for more details on what it does).

    ---
    title: "Test"
    format: 
      pdf:
        include-in-header:
          text: |
            \setlength{\defaultaddspace}{0pt}
    ---
    
    ```{r}
    library(kableExtra)
    dat <- data.frame(v1 = letters[1:10], v2 = 1:10)
    kable(dat) |> 
      kable_styling()
    ```
    

    enter image description here


    Issue explanation

    In kable(dat) |> kable_styling() no format argument gets passed. In that case, knitr:::kable_format() defaults to format = "pipe".

    This does not result in larger effects in knitr::kable() because within this function knitr:::kable_format_latex() changes format to "latex" because is_latex_output() evaluates to TRUE.

    However, in kableExtra::kableStyling() the function kableExtra:::md_table_parser() gets invoked and this function passes no linesep argument to kbl():

    return(kbl(table_matrix, col.names=header_row, align=alignment,
                caption=table_caption, booktabs = TRUE,
                longtable = TRUE))
    

    such that the default gets used (what is also discussed in this answer):

    linesep = if (booktabs) c('', '', '', '', '\\addlinespace') else '\\hline'