Reputation: 65
I'm using the kableExtra package to output a table to PDF in R markdown.
I use the command group_rows() to group some rows of my table together.
The text in some rows of my first column is too long for the column width, so it is broken into two lines. However, there is no indentation of the second line. Is there a way to either indent also the second line or remove the indentation overall?
Increasing the column width so the text won't be spread over two lines is unfortunately no option since I have way more columns in my real table.
This is a subset of my data frame:
data <- structure(list(`Control variables` = c("GDP growth", "GDP per capita",
"Top income tax rate", "Right-wing executive"), Treated = structure(c("2.29",
"21,523.57", "0.70", "0.62"), class = "AsIs"), top10_synthetic = structure(c("3.37", "19,939.72", "0.68", "0.63"), class = "AsIs"), top10_mean = structure(c("2.95", "30,242.60", "0.64", "0.43"), class = "AsIs")), .Names = c("Control variables", "Treated", "top10_synthetic", "top10_mean"), row.names = c(NA, 4L), class = "data.frame")
This is the code I am using:
```{r}
kable(data, "latex", caption = "table 1", booktabs = T, col.names = c("Control variables", "Treated", "Synthetic", "Mean")) %>%
add_header_above(c("", "", "Top 10%" = 2)) %>%
group_rows("UK", 1, 2) %>%
group_rows("Japan", 3, 4, latex_gap_space = "0.8cm") %>%
footnote(general = "xxx") %>%
kable_styling(latex_options = c("HOLD_position", "scale_down")) %>%
column_spec(1, width = "3cm")
```
This is how the .pdf output looks like. As you can see, e.g. the text "top income tax rate" is split into two lines and I would like the second line to be indented just like the first line.
Thank you for any tips!
Upvotes: 4
Views: 2104
Reputation: 44788
If you just run the chunk in the R console, you'll see this LaTeX output:
\begin{table}[H]
\caption{\label{tab:}table 1}
\centering
\resizebox{\linewidth}{!}{
\begin{tabular}[t]{>{\raggedright\arraybackslash}p{3cm}lll}
\toprule
\multicolumn{1}{c}{} & \multicolumn{1}{c}{} & \multicolumn{2}{c}{Top 10\%} \\
\cmidrule(l{2pt}r{2pt}){3-4}
Control variables & Treated & Synthetic & Mean\\
\midrule
\addlinespace[0.3em]
\multicolumn{4}{l}{\textbf{UK}}\\
\hspace{1em}GDP growth & 2.29 & 3.37 & 2.95\\
\hspace{1em}GDP per capita & 21,523.57 & 19,939.72 & 30,242.60\\
\addlinespace[0.8cm]
\multicolumn{4}{l}{\textbf{Japan}}\\
\hspace{1em}Top income tax rate & 0.70 & 0.68 & 0.64\\
\hspace{1em}Right-wing executive & 0.62 & 0.63 & 0.43\\
\bottomrule
\multicolumn{4}{l}{\textit{Note: }}\\
\multicolumn{4}{l}{xxx}\\
\end{tabular}}
\end{table}
As you can see, kableExtra
isn't putting in a line break in that title, LaTeX is doing it. This means you need a LaTeX fix for the problem. Maybe someone else knows an easier one, but the best I could find is the following: wrap the long row title in a minipage
environment, and fiddle with the spacing to look better.
Since this is kind of messy, I'd write an R function to do it:
inMinipage <- function(x, width)
paste0("\\begin{minipage}[t]{",
width,
"}\\raggedright\\setstretch{0.8}",
x,
"\\vspace{1.2ex}\\end{minipage}")
This needs to be called on the data being put into the table, and kable
needs to be told not to escape those backslashes (using escape = FALSE
). In addition, the \setstretch
command comes from the setspace
LaTeX package. So overall your sample document would look like this:
---
output:
pdf_document:
extra_dependencies: setspace
---
```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = TRUE)
library(kableExtra)
library(knitr)
```
```{r}
inMinipage <- function(x, width)
paste0("\\begin{minipage}[t]{",
width,
"}\\raggedright\\setstretch{0.8}",
x,
"\\end{minipage}")
data <- structure(list(`Control variables` = c("GDP growth", "GDP per capita", "Top income tax rate", "Right-wing executive"), Treated = structure(c("2.29",
"21,523.57", "0.70", "0.62"), class = "AsIs"), top10_synthetic = structure(c("3.37", "19,939.72", "0.68", "0.63"), class = "AsIs"), top10_mean = structure(c("2.95", "30,242.60", "0.64", "0.43"), class = "AsIs")), .Names = c("Control variables", "Treated", "top10_synthetic", "top10_mean"), row.names = c(NA, 4L), class = "data.frame")
data[[1]] <- inMinipage(data[[1]], "2.5cm")
kable(data, "latex", caption = "table 1", booktabs = T, col.names = c("Control variables", "Treated", "Synthetic", "Mean"), escape = FALSE) %>%
add_header_above(c("", "", "Top 10%" = 2)) %>%
group_rows("UK", 1, 2) %>%
group_rows("Japan", 3, 4, latex_gap_space = "0.8cm") %>%
footnote(general = "xxx") %>%
kable_styling(latex_options = c("HOLD_position", "scale_down")) %>%
column_spec(1, width = "3cm")
```
With that code I see this:
The spacing isn't quite right, but it's getting close. I hope this helps.
Upvotes: 2