0

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

stefan
  • 90,330
  • 6
  • 25
  • 51
jsimpsno
  • 448
  • 4
  • 19

2 Answers2

2

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

stefan
  • 90,330
  • 6
  • 25
  • 51
  • Both of these are great! I decided to give the second answer the check as it fit my needs slightly better with arranging plot widths to fit my layout. – jsimpsno Apr 06 '23 at 05:09
1

One way is to useexport::graph2ppt which converts plots into powerpoint slides. graph2ppt has a parameter append, which appends the plots to the same pptx if set to TRUE.

library(ggpubr)
library(export)
library(purrr)
library(ggplot2)
library(dplyr)

days <- c(1:3)
plts <- map(
  days,
  function(x){
    base_plot <- airquality |> filter(Day == x) |> ggplot()
    
    scatter1 <- base_plot + geom_point(aes(Ozone,Solar.R)) + ggtitle(paste0("Day",x))
    line <- base_plot + geom_line(aes(Ozone,Wind)) + ggtitle(paste("Day",x))
    scatter2 <-  base_plot + geom_point(aes(Ozone,Temp)) + ggtitle(paste("Day",x))
    bar <- base_plot + geom_bar(aes(Wind,Temp),stat='identity') + ggtitle(paste("Day",x))
    
    return(ggarrange(scatter1, line, scatter2, bar, ncol=2, nrow=2))
  }
)

# export to ppt
for (p in plts){
  graph2ppt(p, file="slide", append=T)
}

enter image description here enter image description here enter image description here

nightstand
  • 329
  • 2
  • 11