haozhu233 / kableExtra

Construct Complex Table with knitr::kable() + pipe.
https://haozhu233.github.io/kableExtra/
Other
689 stars 147 forks source link

issues with `collapse_rows()` and `kable_styling()` in LaTeX #671

Open unDocUMeantIt opened 2 years ago

unDocUMeantIt commented 2 years ago

Description collapse_rows() and kable_styling() seem to function well for HTML output. but when they're used for LaTeX/PDF generation, you can quickly run into broken tables. i've noticed that it's next to impossible to call kable_styling() before collapse_rows() if you want the latter to have any effect, and that you can't use any latex_hline combined with collapse_rows() if you want the vertical alignment to be correct.

A reproducible example

---
#title: kableExtra demo
#latex_engine: pdflatex
output:
  pdf_document:
    latex_engine: pdflatex
    extra_dependencies: ["array", "booktabs", "colortbl", "float", "longtable", "multirow", "xcolor"]
---

```{r setup, include=FALSE}
library(kableExtra)

x <- data.frame(
    a=rep(letters[1:2], each=10),
    b=rep(letters[3:12], each=2),
    c=1:20
)
# we'll reuse this basic kable object
x_kbl <- kbl(
    x,
    format="latex",
    booktabs=TRUE,
    escape=FALSE
)

collapse_rows() after kable_styling()

It fails completely:

x_kbl_kc <- kable_styling(
    x_kbl,
    full_width=FALSE,
    latex_options=c("striped", "HOLD_position")
)
x_kbl_kc <- collapse_rows(
    x_kbl_kc,
    columns=1:2,
    valign="top",
    latex_hline="custom",
    custom_latex_hline=2
)
x_kbl_kc

\newpage

collapse_rows() before kable_styling()

Almost works, but top alignment collapsed rows is off:

x_kbl_ck <- collapse_rows(
    x_kbl,
    columns=1:2,
    valign="top"
)
x_kbl_ck <- kable_styling(
    x_kbl_ck,
    full_width=FALSE,
    latex_options=c("striped", "HOLD_position")
)
x_kbl_ck

The odd allignment is due to the fact that multirow is being thrown off by extra space added between data rows by lines.

\newpage

collapse_rows() without hline

Fixes top alignment:

x_kbl_nh <- collapse_rows(
    x_kbl,
    columns=1:2,
    valign="top",
    latex_hline="none"
)
x_kbl_nh <- kable_styling(
    x_kbl_nh,
    full_width=FALSE,
    latex_options=c("striped", "HOLD_position")
)
x_kbl_nh

Save to `demo.rmd` and generate PDF:

```r
require(knitr)
require(rmarkdown)
render(
  input="demo.rmd",
  output_format=NULL,
  output_file="demo.pdf",
  output_dir="/tmp",
  intermediates_dir="/tmp",
  #quiet=TRUE,
  clean=FALSE
)

Results

image

image

image

ghost commented 2 years ago

Did you get anywhere with this? I am having the same issue

unDocUMeantIt commented 2 years ago

no real solution yet. i tried to fix the resulting LaTeX file for a while, to get an idea what kableExtra could generate. now i'm not sure this can be implemented cleanly using the multirow package at all. workarounds that helped with one table were useless for others. i'd suggest to drop the use of multirow completely and try with plain old empty table cells instead.

krlmlr commented 2 years ago

Can you please try the new row_group_label_position = "first"?