Search code examples
rpdfr-markdownreportknitr

Create tables using rmarkdown in loop


I'd like to create a pdf report for each cylinder ('cyl') between the 3 possibilities (4, 6 and 8) in a separate table. But, I need to create one table for each cylinder in a loop and for this I try to do:

    library(knitr)
    library (rmarkdown)
    data(mtcars)
    id.cyl <-unique(mtcars$cyl)
    for(i in 1:id.cyl){
    mtcars.sub<- 
    mtcars[mtcars$cyl==id.mtcars[i],]
    kagle(mtcars.sub)
    }
    render("my_loop_report.pdf", 
    pdf_document())

This code doesn't work and I need some suggestions to solve it. Please any help with it?


Solution

  • Create an .rmd file that generates the report, and pass the cylinder as a value.

    Here is the .rmd file (say, cylinder.rmd)

    ---
    title: "cylinder_report"
    author: "author_name"
    date: "2023-01-25"
    output: pdf_document
    params:
      cylinder: 0
    ---
    
    ``{r setup, include=FALSE}
    knitr::opts_chunk$set(echo = TRUE)
    df = mtcars
    ``
    
    ## Cylinder `r params$cylinder`
    ``{r output, echo=FALSE}
    knitr::kable(df[df$cyl == params$cylinder,])
    ``
    

    Separately, you can then loop through the cylinder values, each time passing the cylinder value

    cyls = unique(mtcars$cyl)
    for(cyl in cyls) {
      rmarkdown::render(
        input = "cylinder.Rmd",
        output_file = paste0("cylinder_report_", cyl),
        params = list(cylinder = cyl)
        )
    }
    

    This will produce cylinder_report_4.pdf, cylinder_report_6.pdf, and cylinder_report_8.pdf.

    (Note, in this toy example, you don't even have to pass the parameter; in fact, loading mtcars into df and subsetting it within the .rmd is not necessary. When you use `rmarkdown::render(), objects in the environment are available to the .rmd file, so you could also subset the data in the loop outside the rmd file, like this,

    cyls = unique(mtcars$cyl)
    for(cyl in cyls) {
      df = mtcars[mtcars$cyl == cyl,]
      rmarkdown::render(
        input = "cylinder.Rmd",
        output_file = paste0("cylinder_report_", cyl)
        )
    }
    

    and the .rmd could be simplifed to this (note, no parameter, no creation of df, no subsetting, etc:

    ---
    title: "cylinder_report"
    author: "author_name"
    date: "2023-01-25"
    output: pdf_document
    ---
    
    ``{r setup, include=FALSE}
    knitr::opts_chunk$set(echo = TRUE)
    ``
    
    ## Cylinder `r cyl`
    ``{r output, echo=FALSE}
    knitr::kable(df)
    ``
    

    )