kableExtra icon indicating copy to clipboard operation
kableExtra copied to clipboard

threeparttable overrides centering with caption

Open grantmcdermott opened this issue 3 years ago • 0 comments
trafficstars

Describe the bug

Using add_footnote(..., threeparttable = TRUE) overrides kable_styling(position = "center") if a caption is also provided. First reported here but identified as an upstream bug.

To Reproduce

Here's a screenshot of a PDF demonstrating the bug.

kbl

To break down what's happening above, let's cat the raw LaTeX code for each example. First, quickly load the package and create the table.

library(kableExtra)
dat = mtcars[1,1:4]

In the base case with threeparttable turned off, the \centering option comes immediately before the begin{tabular} environment. So this works as expected.

kbl(dat, caption = "A nice table", format = "latex") %>%
  add_footnote("A short note.", threeparttable = FALSE) %>% ## NO 3PT
  kable_styling(position = "center") %>%
  cat()
#> \begin{table}
#> 
#> \caption{A nice table}
#> \centering
#> \begin{tabular}[t]{l|r|r|r|r}
#> \hline
#>   & mpg & cyl & disp & hp\\
#> \hline
#> Mazda RX4 & 21 & 6 & 160 & 110\\
#> \hline
#> \multicolumn{5}{l}{\textsuperscript{a} A short note.}\\
#> \end{tabular}
#> \end{table}

In contrast, switching threeparttable on leads to a new begin{threeparttable} environment, which precedes the \centering option. So the latter is overridden, leading to the unexpected left-alignment of the table.

kbl(dat, caption = "A nice table", format = "latex") %>%
  add_footnote("A short note.", threeparttable = TRUE) %>% # CHANGED
  kable_styling(position = "center") %>%
  cat()
#> \begin{table}
#> 
#> \begin{threeparttable}
#> \caption{\label{tab:unnamed-chunk-2}A nice table}
#> \centering
#> \begin{tabular}[t]{l|r|r|r|r}
#> \hline
#>   & mpg & cyl & disp & hp\\
#> \hline
#> Mazda RX4 & 21 & 6 & 160 & 110\\
#> \hline
#> \end{tabular}
#> \begin{tablenotes}
#> \small
#> \item [a] A short note.
#> \end{tablenotes}
#> \end{threeparttable}
#> \end{table}

Finally, to emphasize the interplay between these elements, note that turning off caption leads back to the correct behaviour, where \centering precedes the begin{threeparttable} environment.

kbl(dat, caption = NULL, format = "latex") %>% ## Now caption = NULL
  add_footnote("A short note.", threeparttable = TRUE) %>%
  kable_styling(position = "center") %>%
  cat()
#> \begin{table}
#> \centering
#> \begin{threeparttable}
#> \begin{tabular}[t]{l|r|r|r|r}
#> \hline
#>   & mpg & cyl & disp & hp\\
#> \hline
#> Mazda RX4 & 21 & 6 & 160 & 110\\
#> \hline
#> \end{tabular}
#> \begin{tablenotes}
#> \small
#> \item [a] A short note.
#> \end{tablenotes}
#> \end{threeparttable}
#> \end{table}

Solution

Calling kable_styling(position = "center") should always lead inject \centering directly below \begin{table}, rather than after an intermediate environment like \begin{threeparttable}. I imagine this is true for other arguments that apply to kable_styling, so should hopefully be a relatively simple fix.

grantmcdermott avatar Mar 09 '22 18:03 grantmcdermott