Jia Gao
Jia Gao

Reputation: 1292

Use kableExtra to manipulate and save tex file after modelsummary

My work flow is R + Overleaf. So often times I need to generate regression table in R and print it out in overleaf. I recently came accross the the modelsummary package which is super handy and powerful in doing so. But I stumble upon an issue and it took me an entire day without finding a proper solution, so here I am.

I generated a very large (too wide and too long) tex table using modelsummary directly and it can not be fit into one page when I compile it use overleaf. The common LaTeX fix is to use longtable but it seems like .tex file generated by modelsummary does not compatiable to the longtable command. Then I turn to the kableExtra option to scale down the table and make the font size small. Which, if works, is the best to do it since I have hundreds of such .tex files and it would extremely inefficient if I need to change them manually one by one. But I can not get it work since the saved .tex file is either in html format (when output=kableExtra is specified in the modelsummary function) or is empty (when output=latex is specified in the modelsummary function).

Any help will be deeply appreciated and I think this will benefit those who share the same or similar workflow with me in great deal. Thanks so much in advance. Below is an minimum example to play around with.

# update.packages()
rm(list = ls())
library(kableExtra)
library(modelsummary)
library(tidyr)
options(knitr.table.format = "latex")
options("modelsummary_format_numeric_latex" = "plain")

url <- 'https://vincentarelbundock.github.io/Rdatasets/csv/HistData/Guerry.csv'
dat <- read.csv(url)

models <- list(
  "OLS 1"     = lm(Donations ~ Literacy + Clergy, data = dat),
  "Poisson" = glm(Donations ~ Literacy + Commerce, family = poisson, data = dat),
  "OLS 2"     = lm(Crime_pers ~ Literacy + Clergy, data = dat)
)

# Generate modelsummary output as a kable object (for compatibility)
raw_output <- modelsummary(models = models, output = "kableExtra")

# Apply kableExtra styling to the kable object
styled_output <- raw_output %>%
  kable_styling(font_size = 7, latex_options = c('scale_down', 'HOLD_position'))

# Save the styled LaTeX output to a file
kableExtra::save_kable(
  styled_output,
  file = "test.tex"
)

--------------------------EDIT----------------------- Based on Vincent's comment, I changed the code to the following:

raw_output <- modelsummary(models = models, output = "tinytable") |>
  theme_tt("resize", width=0.8) |>
  save_tt('test.tex', overwrite = TRUE)

And tried to compile the tex.file using the following environment in Overleaf:

\documentclass{article}
\usepackage{tabularray}
\usepackage{float}
\usepackage{graphicx}
\usepackage{codehigh}
\usepackage[normalem]{ulem}
\usepackage{tcolorbox}
\usepackage{adjustbox}
\usepackage{pdflscape}
\usepackage{subcaption}
\usepackage[skip=1ex, 
            font={small, sf},
            labelfont=bf
            ]{caption}  % new
\usepackage{tabularray}
\usepackage{tblr-extras}
\UseTblrLibrary{amsmath, booktabs,
                caption, siunitx}    % new
%\usepackage{amsmath}   %   Loaded by TblrLibrary
\usepackage{acronym}
\newcommand{\tinytableTabularrayUnderline}[1]{\underline{#1}}
\newcommand{\tinytableTabularrayStrikeout}[1]{\sout{#1}}
\NewTableCommand{\tinytableDefineColor}[3]{\definecolor{#1}{#2}{#3}}

\graphicspath{{./images}}
\begin{landscape}

\input{tables/test.tex}
\end{landscape}

Below is the first error:

Missing $ inserted.
You need to enclose all mathematical expressions and symbols with special markers. These special markers create a ‘math mode’.

Use $...$ for inline math mode, and \[...\]or one of the mathematical environments (e.g. equation) for display math mode.

This applies to symbols such as subscripts ( _ ), integrals ( \int ), Greek letters ( \alpha, \beta, \delta ) and modifiers (\vec{x}, \tilde{x}).

Learn more

This is usually a longtable error.

Upvotes: 0

Views: 108

Answers (1)

user2554330
user2554330

Reputation: 44957

I don't use Overleaf, so I can't tell you if this will work there, but I don't see why not. This is how to modify your code to produce longtable output. Note that it can't be resized by kableExtra, so I've left out that option.

First you output a dataframe from modelsummary(), then you format it in kableExtra.

# Generate modelsummary output as a data.frame
raw_output <- modelsummary(models = models, output = "data.frame")

# Apply kableExtra styling to the kable object
styled_output <- raw_output %>% 
  kbl(format = "latex", longtable = TRUE, booktabs=TRUE) %>%
  kable_styling(font_size = 7, latex_options = c('HOLD_position'))

Upvotes: 0

Related Questions