rdplyrr-markdownofficer

iterate through plots and create powepoint slides rmarkdown


I would like to create a powepoint slide deck in rmarkdown by iteratively building the slides for each Day. See example below and code that makes a function to output the plots. I just don't know how to add these plots to a slide deck without saving and manually adding them in.

library(ggplot2)
library(tidyverse)


airquality<-datasets::airquality

glimpse(airquality)
vec<-unique(airquality$Day)

id=1

fctn<-function(id){
airquality_filtered<- airquality%>%filter(Day==id)
ggplot(airquality_filtered)+geom_point(aes(Ozone,Solar.R))+ggtitle(paste("Day",id))
ggsave(plot=last_plot(),paste("C:\\Users\\",id,"plot1.png"),width=6.25,height=3.75)
ggplot(airquality_filtered)+geom_line(aes(Ozone,Wind))+ggtitle(paste("Day",id))
ggsave(plot=last_plot(),paste("C:\\Users\\",id,"plot2.png"),width=6.25,height=3.75)
ggplot(airquality_filtered)+geom_point(aes(Ozone,Temp))+ggtitle(paste("Day",id))
ggsave(plot=last_plot(),paste("C:\\Users\\",id,"plot3.png"),width=6.25,height=3.75)
ggplot(airquality_filtered)+geom_bar(aes(Wind,Temp),stat='identity')+ggtitle(paste("Day",id))
ggsave(plot=last_plot(),paste("C:\\Users\\",id,"plot4.png"),width=6.25,height=3.75)

}

lapply(1:3,fctn)

This would be the desired output with a slide for each Day ie Day 1 (slide 1) Day 2 (slide 2) etc.

enter image description here

enter image description here


Solution

  • If a pure officer solution is fine for you, then the following code will give you your desired result.

    First I use patchwork::wrap_plots to glue the four plots per day together and store them in a list. Afterwards you could use a for loop to export your plots to a pptx by first adding a slide and e.g. placing the plots in an appropriate placeholder.

    The tricky part is to get the names of the layouts and the placeholders. To this end have a look at officer::layout_summary and officer::layout_properties.

    Using a minimal reproducible example based on the default pptx template shipped with officer:

    library(officer)
    library(tidyverse)
    library(patchwork)
    
    fctn <- function(id) {
      title <- paste("Day", id)
      airquality_filtered <- airquality %>% filter(Day == id)
      list(
        ggplot(airquality_filtered) +
          geom_point(aes(Ozone, Solar.R)) +
          ggtitle(title),
        ggplot(airquality_filtered) +
          geom_line(aes(Ozone, Wind)) +
          ggtitle(title),
        ggplot(airquality_filtered) +
          geom_point(aes(Ozone, Temp)) +
          ggtitle(title),
        ggplot(airquality_filtered) +
          geom_bar(aes(Wind, Temp), stat = "identity") +
          ggtitle(title) 
      ) |> 
        wrap_plots(ncol = 2)
    }
    
    plots <- lapply(1:3, fctn)
    
    pptx <- read_pptx()
    
    for (i in seq_along(plots)) {
      pptx <- add_slide(pptx, layout = "Title and Content", master = "Office Theme")
      pptx <- ph_with(pptx, plots[[i]], location = ph_location_label(ph_label = "Content Placeholder 2") )
      pptx <- ph_with(pptx, paste("Day", i), location = ph_location_label(ph_label = "Title 1") )
    }
    
    print(pptx, "my_plots.pptx")
    

    enter image description here