Search code examples
rr-markdownknitrkablekableextra

Knitr / kable captions for each elements of a list


I currently have to create a .pdf document with R Markdown. I am using the knitr package to "convert" my dataframes to LaTeX. I usually have no problems doing it but this time I'm quite not sure how to resolve my problem.

I need to get the title of each elements (some dataframes) of my list to appear as a caption in the .pdf file.

Here is an example of the data I have :

library(knitr)
library(kableExtra)

df1 <- data.frame(col1 = c(1,2,3), col2 = c("a", "b", "c"))
df2 <- data.frame(col1 = c(6,7,8), col2 = c("d", "e", "f"))
list <- list("df1" = df1, "df2" = df2)

print(list)

$`df1`
  col1 col2
1    1    a
2    2    b
3    3    c

$df2
  col1 col2
1    6    d
2    7    e
3    8    f

My knitr and kableExtra code :

my_function <- function(list){
    kable(list, "latex", longtable = T,
              caption = "df1 and df2 respectively") %>%
          kable_styling(font_size = 7,
                        latex_options = c("repeat_header"),
                        full_width = F)
}

print(lapply(list, my_function))

At the moment the caption for both tables on the output document would be df1 and df2 respectively when I would like to have df1 for the first and df2 for the second and so on...

I am not used to list() inside kable() since I mostly use data.frame/data.table. I have try to replace the caption with arguments using names(), cat(), ... and didn't get the result I wanted. I'm pretty sure there is something simple to this.

Anyone could help me? Thank you.


Solution

  • You could print the tables separately in a for-loop, as also suggested here: Unexpected behavior of kable when called from lapply or from function with print statement.

    Rmarkdown

    ---
    title: "List of tables"
    output: 
      pdf_document
    header-includes:
       - \usepackage{longtable}
    ---
    
    ```{r tables, results = "asis", echo = FALSE}
    library(knitr)
    library(kableExtra)
    
    ## data
    df1 <- data.frame(col1 = c(1,2,3), col2 = c("a", "b", "c"))
    df2 <- data.frame(col1 = c(6,7,8), col2 = c("d", "e", "f"))
    ls <- list(df1 = df1, df2 = df2)
    
    ## tables
    for(i in seq_along(ls)) {
      print(
          kable(ls[[i]], format = "latex", caption = names(ls)[i], longtable = TRUE) %>%
              kable_styling(font_size = 7, latex_options = "repeat_header", full_width = FALSE)
      )
    }
    
    ```
    

    PDF output

    PDF_output