In RMarkdown, I need to knit a table where columns A and B will be merged (if B is not null); in the merged columns, texts from A and B must be in different lines and styles. All columns must have identical vertical alignment.
What I tried with PDF output and Latex:
---
output:
pdf_document:
latex_engine: xelatex
keep_tex: true
---
```{r}
library(gt)
library(tibble)
df <- tibble(
A = c("a1", "a2"),
B = c("b1", NA),
C = c("c1", "c2")
)
df %>%
gt() %>%
cols_merge(
columns = c(A, B),
pattern = "{1}<< \\\\{{\\scriptsize {2}}}>>"
)
```
is insatisfactory as the text in column C ("c1") is moved down because of a new line in column A.
knitted PDF
Expected output:
I will accept any solutions generating a PDF or Word output.
Using solution by Tim G, I ran into problems when using accented characters. The accent seems to be interpreted as a line break.
---
output:
pdf_document:
latex_engine: lualatex
header-includes:
- \usepackage{makecell}
- \setmainfont{Latin Modern Roman}
---
```{r, echo=FALSE}
library(gt)
library(tibble)
df <- tibble(
A = c("á1á", "a2"),
B = c("b1", NA),
C = c("c1", "c2")
)
df |>
gt() |>
cols_merge(
columns = c(A, B),
pattern = "\\makecell[tc]{{{1}<< \\\\ {{\\scriptsize {2}}}>>}}"
)
```
knits:

> sessionInfo()
R version 4.4.1 (2024-06-14 ucrt)
Platform: x86_64-w64-mingw32/x64
Running under: Windows 11 x64 (build 26100)
Matrix products: default
locale:
[1] LC_COLLATE=Czech_Czechia.utf8 LC_CTYPE=Czech_Czechia.utf8 LC_MONETARY=Czech_Czechia.utf8
[4] LC_NUMERIC=C LC_TIME=Czech_Czechia.utf8
time zone: Europe/Prague
tzcode source: internal
attached base packages:
[1] stats graphics grDevices utils datasets methods base
loaded via a namespace (and not attached):
[1] compiler_4.4.1 fastmap_1.2.0 cli_3.6.3 htmltools_0.5.8.1 tools_4.4.1
[6] rstudioapi_0.17.1 yaml_2.3.10 rmarkdown_2.29 knitr_1.50 xfun_0.52
[11] digest_0.6.37 rlang_1.1.6 evaluate_1.0.4
> system("xelatex --version")
XeTeX 3.141592653-2.6-0.999997 (TeX Live 2025)
kpathsea version 6.4.1
Copyright 2025 SIL International, Jonathan Kew and Khaled Hosny.
There is NO warranty. Redistribution of this software is
covered by the terms of both the XeTeX copyright and
the Lesser GNU General Public License.
For more information about these matters, see the file
named COPYING and the XeTeX source.
Primary author of XeTeX: Jonathan Kew.
Compiled with ICU version 76.1; using 76.1
Compiled with zlib version 1.3.1; using 1.3.1
Compiled with FreeType2 version 2.13.3; using 2.13.3
Compiled with Graphite2 version 1.3.14; using 1.3.14
Compiled with HarfBuzz version 10.2.0; using 10.2.0
Compiled with libpng version 1.6.46; using 1.6.46
Compiled with pplib version v2.2
Compiled with fontconfig version 2.15.0; using 2.15.0
[1] 0
> system("lualatex --version")
This is LuaHBTeX, Version 1.22.0 (TeX Live 2025)
Development id: 7673
.tex file:
% Options for packages loaded elsewhere
\PassOptionsToPackage{unicode}{hyperref}
\PassOptionsToPackage{hyphens}{url}
\documentclass[
]{article}
\usepackage{xcolor}
\usepackage[margin=1in]{geometry}
\usepackage{amsmath,amssymb}
\setcounter{secnumdepth}{-\maxdimen} % remove section numbering
\usepackage{iftex}
\ifPDFTeX
\usepackage[T1]{fontenc}
\usepackage[utf8]{inputenc}
\usepackage{textcomp} % provide euro and other symbols
\else % if luatex or xetex
\usepackage{unicode-math} % this also loads fontspec
\defaultfontfeatures{Scale=MatchLowercase}
\defaultfontfeatures[\rmfamily]{Ligatures=TeX,Scale=1}
\fi
\usepackage{lmodern}
\ifPDFTeX\else
% xetex/luatex font selection
\fi
% Use upquote if available, for straight quotes in verbatim environments
\IfFileExists{upquote.sty}{\usepackage{upquote}}{}
\IfFileExists{microtype.sty}{% use microtype if available
\usepackage[]{microtype}
\UseMicrotypeSet[protrusion]{basicmath} % disable protrusion for tt fonts
}{}
\makeatletter
\@ifundefined{KOMAClassName}{% if non-KOMA class
\IfFileExists{parskip.sty}{%
\usepackage{parskip}
}{% else
\setlength{\parindent}{0pt}
\setlength{\parskip}{6pt plus 2pt minus 1pt}}
}{% if KOMA class
\KOMAoptions{parskip=half}}
\makeatother
\usepackage{graphicx}
\makeatletter
\newsavebox\pandoc@box
\newcommand*\pandocbounded[1]{% scales image to fit in text height/width
\sbox\pandoc@box{#1}%
\Gscale@div\@tempa{\textheight}{\dimexpr\ht\pandoc@box+\dp\pandoc@box\relax}%
\Gscale@div\@tempb{\linewidth}{\wd\pandoc@box}%
\ifdim\@tempb\p@<\@tempa\p@\let\@tempa\@tempb\fi% select the smaller of both
\ifdim\@tempa\p@<\p@\scalebox{\@tempa}{\usebox\pandoc@box}%
\else\usebox{\pandoc@box}%
\fi%
}
% Set default figure placement to htbp
\def\fps@figure{htbp}
\makeatother
\setlength{\emergencystretch}{3em} % prevent overfull lines
\providecommand{\tightlist}{%
\setlength{\itemsep}{0pt}\setlength{\parskip}{0pt}}
\usepackage{makecell}
\setmainfont{Latin Modern Roman}
\usepackage{booktabs}
\usepackage{caption}
\usepackage{longtable}
\usepackage{colortbl}
\usepackage{array}
\usepackage{anyfontsize}
\usepackage{multirow}
\usepackage{bookmark}
\IfFileExists{xurl.sty}{\usepackage{xurl}}{} % add URL line breaks if available
\urlstyle{same}
\hypersetup{
hidelinks,
pdfcreator={LaTeX via pandoc}}
\author{}
\date{\vspace{-2.5em}}
\begin{document}
\begin{verbatim}
## Warning: package 'gt' was built under R version 4.4.3
\end{verbatim}
\begin{verbatim}
## Warning: package 'tibble' was built under R version 4.4.3
\end{verbatim}
\begin{table}[t]
\fontsize{12.0pt}{14.0pt}\selectfont
\begin{tabular*}{\linewidth}{@{\extracolsep{\fill}}ll}
\toprule
A & C \\
\midrule\addlinespace[2.5pt]
\makecell[tc]{\\'a1\\'a \\ {\scriptsize b1}} & c1 \\
\makecell[tc]{a2} & c2 \\
\bottomrule
\end{tabular*}
\end{table}
\end{document}
One option could be using makecell with the top-center tc argument.
This only works with gt_1.0.0
1.1.0 introduced some changes #1912 which changed how latex escaping works especially when mixed with pattern handles. It looks like a regression bug - as of writing this, I could not find a work around.
---
output:
pdf_document:
latex_engine: xelatex
header-includes:
- \usepackage{makecell}
---
```{r, echo=FALSE}
library(gt)
library(tibble)
df <- tibble(
A = c("a1", "a2"),
B = c("b1", NA),
C = c("c1", "c2")
)
df |>
gt() |>
cols_merge(
columns = c(A, B),
pattern = "\\makecell[tc]{{{1}<< \\\\ {{\\scriptsize {2}}}>>}}"
)
```
giving

It also works, if I replace "a1" with "á1á"

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With