Search code examples
rknitrkablekableextramodelsummary

Adding a LaTeX reference label to a table in modelsummary


I'm trying to produce tables in R (not RMarkdown, as this question helps answer) with modelsummary and I'm having a tough time adding reference labels (e.g., tab:hello). As Vincent points out in this answer, extra arguments to modelsummary should be pushed forward automatically, but it seems this does not work with LaTeX labels. Here's an example:

library(modelsummary)
library(kableExtra)

x <- rnorm(100)
y <- rnorm(100)

modelsummary(lm(y ~ x),
             output = "latex",
             caption = "test",
             label = "hello")

This produces:

\begin{table}
\caption{test}
\centering
\begin{tabular}[t]{lc}
\toprule
  & Model 1\\
\midrule
(Intercept) & \num{-0.143}\\
 & (\num{0.100})\\
x & \num{-0.023}\\
 & (\num{0.092})\\
\midrule
Num.Obs. & \num{100}\\
R2 & \num{0.001}\\
R2 Adj. & \num{-0.010}\\
AIC & \num{283.4}\\
BIC & \num{291.2}\\
Log.Lik. & \num{-138.698}\\
F & \num{0.061}\\
\bottomrule
\end{tabular}
\end{table}

Meanwhile, this works fine with a call to kable:

df <- cbind.data.frame(x, y)
kable(head(df), "latex",
      caption = "test",
      label = "hello")

Which produces:

\begin{table}
\caption{\label{tab:hello}test}
\centering
\begin{tabular}[t]{r|r}
\hline
x & y\\
\hline
0.8078318 & -0.0219732\\
\hline
0.4660209 & -0.9973773\\
\hline
-1.0620694 & -0.1360954\\
\hline
0.5639881 & 0.0185161\\
\hline
0.3459854 & 0.1333345\\
\hline
-0.8035314 & -0.0759982\\
\hline
\end{tabular}
\end{table}

Weirdly, this only works when specifying a caption too. Defining only a label in kable doesn't produce a label.

Ideally, I'd like to only produce a label, but if I have to add a caption too, I can deal with that (since it seems like this is an issue with kable as well---or just with LaTeX tables in general).

Thank you in advance for the help! It's much appreciated.


Solution

  • I believe this is a limitation in LaTeX itself, which requires a caption for proper table numbering and referencing. See this answer for a discussion and an alternative mechanism:

    https://tex.stackexchange.com/a/438267/16188

    Beyond that, I think it is useful to note that this is not a modelsummary-specific issue. As you may know, modelsummary supports several table-making packages that produce different output formats: kableExtra, gt, flextable, or huxtable. The default table-maker for LaTeX is kableExtra.

    Here’s a minimal example in kableExtra that reproduces the same problem:

    library(kableExtra)
    dat <- mtcars[1:3, 1:3]
    

    No label appears:

    kbl(dat, format = "latex", label = "fig:test") |>
        kable_styling()
    #> \begin{table}
    #> \centering
    #> \begin{tabular}[t]{l|r|r|r}
    #> \hline
    #>   & mpg & cyl & disp\\
    #> \hline
    #> Mazda RX4 & 21.0 & 6 & 160\\
    #> \hline
    #> Mazda RX4 Wag & 21.0 & 6 & 160\\
    #> \hline
    #> Datsun 710 & 22.8 & 4 & 108\\
    #> \hline
    #> \end{tabular}
    #> \end{table}
    

    Label appears:

    kbl(dat, format = "latex", caption = "", label = "fig:test") |>
        kable_styling()
    #> \begin{table}
    #> 
    #> \caption{\label{tab:fig:test}}
    #> \centering
    #> \begin{tabular}[t]{l|r|r|r}
    #> \hline
    #>   & mpg & cyl & disp\\
    #> \hline
    #> Mazda RX4 & 21.0 & 6 & 160\\
    #> \hline
    #> Mazda RX4 Wag & 21.0 & 6 & 160\\
    #> \hline
    #> Datsun 710 & 22.8 & 4 & 108\\
    #> \hline
    #> \end{tabular}
    #> \end{table}
    

    For what it’s worth, in modelsummary I tend to embed the caption directly in the title argument, by using \\ to “escape” the backslash. For example:

    library(modelsummary)
    mod <- lm(mpg ~ hp, mtcars)
    modelsummary(mod, title = "\\label{fig:test}", output = "latex", escape = FALSE)
    #> \begin{table}
    #> 
    #> \caption{\label{fig:test}}
    #> \centering
    #> \begin{tabular}[t]{lc}
    #> \toprule
    #>   & Model 1\\
    #> \midrule
    #> (Intercept) & \num{30.099}\\
    #>  & (\num{1.634})\\
    #> hp & \num{-0.068}\\
    #>  & (\num{0.010})\\
    #> \midrule
    #> Num.Obs. & \num{32}\\
    #> R2 & \num{0.602}\\
    #> R2 Adj. & \num{0.589}\\
    #> AIC & \num{181.2}\\
    #> BIC & \num{185.6}\\
    #> Log.Lik. & \num{-87.619}\\
    #> F & \num{45.460}\\
    #> RMSE & \num{3.86}\\
    #> \bottomrule
    #> \end{tabular}
    #> \end{table}