fred
fred

Reputation: 65

Indentation when line break in group_rows() command - kableExtra package in R markdown

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.

enter image description here

Thank you for any tips!

Upvotes: 4

Views: 2104

Answers (1)

user2554330
user2554330

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:

enter image description here

The spacing isn't quite right, but it's getting close. I hope this helps.

Upvotes: 2

Related Questions