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.
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}