Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

rmarkdown using kable with list of data.tables loses table formatting

I have a rmarkdown document where I want to use a list of data.tables and include them in a PDF/HTML/MS Word document. Each component of the list contains one data.table.

What I'm trying to achieve is to use kable to add all tables in a document with captions.

When I index the data.tables one by one like this

```{r}
 kable(list.of.dts[[1]], caption = paste0("Frequency table for the '", colnames(list.of.dts[[1]])[2], "' variable."))
```

everything is fine and the table is nicely formatted as on the screenshot below.

enter image description here

However, if I try to use lapply to kable all the data.tables in the list like this

```{r}
lapply(X = list.of.dts, FUN = function(i) {
  kable(x = i, caption = paste0("Frequency table for the '", colnames(i)[2], "' variable."))
})
```

to process all data.tables and include them in the document, I get quite basic and crude output like on the screenshot below.

enter image description here

Further, if I just pass the list of data.tables to kable like this

```{r}
kable(list.of.dts)
```

I get all the tables with a better formatting (although not as in the first example), but stacked on top of each other, centered in the middle of the page and I can't add captions:

enter image description here

Does anyone know why is this happening and how can I overcome this issue?

like image 776
panman Avatar asked Sep 06 '25 03:09

panman


1 Answers

The following answer is adapted from edits made to the question by the question author:

I have put result="asis" in the chunk of the first example and saved the output to an object, then returned the object and it did the trick:

```{r, echo = FALSE, results='asis'}
my.list2 <- lapply(X = list.of.dts, FUN = function(i) {
  kable(x = i, caption = paste0("Frequency table for the '", colnames(i)[2], "' variable."))
})
my.list2
```

If I don't save the output to a new object and then return it, then I get a blank document. The above works (see the screenshot below). The only problems are that I see the names of the list components in between the tables and the tables and their captions are aligned in the middle of the page:

enter image description here

EDIT2:

As user20650 (thank you) noted, explicit loop would work better because none of the list components' names will be shown. Besides that, there is no need to assign the results to a new object and then return it. Here is how it looks:

```{r, echo = FALSE, results='asis'}
for(i in list.of.dts) {
  print(kable(x = i, caption = paste0("Frequency table for the '", colnames(i)[2], "' variable.")))
}
```

enter image description here

The only remaining issue is that the tables are still centered in the page.

EDIT3

The last issue (see above) was to align tables and their captions to the left. user20650 made a suggestion that worked for the captions. After I found this email thread, I modified the yaml header as follow, adding these LaTeX options to the header-includes: section:

---
title: "My report"
author: "John Doe"
output: pdf_document
toc: true
header-includes:
  - \usepackage{caption}
  - \captionsetup{justification=raggedright,singlelinecheck=false}
  - \usepackage[margins=raggedright]{floatrow}
---

The first two lines of header-includes: (load the caption package and define the cations' settings) fix the captions' position to left. The last line loads the floatrow package and and fixes the margins.

like image 108
CPlus Avatar answered Sep 07 '25 22:09

CPlus