Home > OS >  How to render multiple plots and tables in Rmarkdown using a loop
How to render multiple plots and tables in Rmarkdown using a loop

Time:06-28

I am working on a Rmarkdown document to show some plots and tables. The code works fine but I got the issue that there are many plots and tables so the process of adding them is really large. My code is next (I need to render to word document):

---
title: "My document"
output: word_document
date: '2022-06-28'
---

```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = TRUE)
```

## Analysis

```{r t1}
library(ggplot2)
library(dplyr)
library(knitr)
#Data
data("iris")
iris
#Create list for plots and tables
List <- split(iris,iris$Species)
#Create plots
plotfun <- function(x)
{
  y <- ggplot(x,aes(x=Sepal.Length,y=Sepal.Width)) 
    geom_point()
  return(y)
}
#Create tables
tablefun <- function(x)
{
  y <- x %>% group_by(Species) %>%
    summarise_all(sum)
  return(y)
}
#Create list of plots and tables
Lplots <- lapply(List, plotfun)
Ltables <- lapply(List, tablefun)
```

Until that is fine. The trouble appears when I need to print the plots and tables. I use this code:

```{r,echo=FALSE,warning=FALSE,message=FALSE,fig.cap=paste0("Figure 1","My plot"),fig.pos='H',fig.align='center',out.width='100%',fig.height=5,fig.width=9}
Lplots[[1]]
```

```{r,echo=FALSE,message=FALSE,warning=FALSE}
kable(Ltables[[1]],caption = paste("Table 1: Summary"),align = c('l',rep('c',4)))
```

But if I have 100 plots and tables, it would be very extensive.

Can somebody help me how I can do something like this:

for(i in 1:length(Lplots))
{

```{r,echo=FALSE,warning=FALSE,message=FALSE,fig.cap=paste0("Figure ",i,"My plot"),fig.pos='H',fig.align='center',out.width='100%',fig.height=5,fig.width=9}
Lplots[[i]]
```

```{r,echo=FALSE,message=FALSE,warning=FALSE}
kable(Ltables[[i]],caption = paste("Table",i," : Summary"),align = c('l',rep('c',4)))
```
}

Many thanks.

CodePudding user response:

You should be able to save the plots by putting the loop within the code chunk.

for(i in length(lPlots)){
    ggsave(fname,lPlots[[i])
}

Another useful option for at least for plots is to use pwalk() as shown here https://cmdlinetips.com/2022/06/create-a-list-of-ggplot-objects-and-save-them-as-files/

CodePudding user response:

Assuming you want to print the plots and tables in your rmarkdown and not save them, you can 1. change code chunk option to results = 'asis' 2. wrap each function call in print() and 3. assign results to some dummy object ("suppress"). If you don't do this it will print ugly output, like NULL or the group title as if it were console output. You'll want to assign to dummy object within each print call and assign the whole function call. I'd guess you'd want your tables and plots together by group, so you can put them in one loop.

{r,echo=FALSE,warning=FALSE,message=FALSE,fig.pos='H',fig.align='center',out.width='100%',fig.height=5,fig.width=9, results='asis'}

lapply(1:length(List), function(i) {
  print(plotfun(List[[i]])  
    ggtitle(paste("My Plot", i)) -> suppress)
  print(kable(tablefun(List[[i]]),caption = sprintf("Table %s: Summary", i),align = c('l',rep('c',4)))) -> suppress
  }) -> suppress

I removed your fig.caption option in code chunk and printed plot and table number dynamically. This should knit into whatever desired output.

  • Related