Search code examples
rpowerpointofficer

Removing graphs, images, and data frames from a powerpoint using R


My intention is to be able to update a powerpoint I have generated in R without having to generate a new deck. For this to work, I need to be able to delete or over-ride in some manner the content that is present in the power point deck I have previously made.

As far as I can tell ph_remove only appears to be the only piece of code that does this. Sadly, as far as I can tell it only works on text, not on graphs, dataframes, or images.

Here is some example code:

This code generates a ppt deck with each type of object:

path_out <- [insert folder directory]

# prep ggplot
p1 <- iris %>% 
  ggplot() +
  geom_point(aes(Sepal.Length,Petal.Length,color = Species), size = 3) +
  theme_minimal()

# prep image
img.file <- file.path(R.home("doc"),"html","logo.jpg")

# prep flextable
ft <- flextable(head(mtcars)) %>%
  autofit()

# prep editable graph (rvg)
p2 <- dml(ggobj = p1)

my_pres <- read_pptx() %>%
  #slide 1
  add_slide(layout = "Title and Content", master = "Office Theme") %>%
  ph_with(value = "Hello World", location = ph_location_type(type = "title")) %>% 
  ph_with(value = "A footer", location = ph_location_type(type = "ftr")) %>% 
  ph_with(value = format(Sys.Date()), location = ph_location_type(type = "dt")) %>% 
  ph_with(value = "Hello world", location = ph_location_type(type = "body")) %>%
  #slide 2
  add_slide() %>%
  ph_with(value = p1, location = ph_location_type("body")) %>% 
  #slide 3
  add_slide() %>%
  ph_with(external_img(img.file, width = 1.39, height = 1.06), location = ph_location_type("body"), use_loc_size = F) %>% # plot an image of specific size
  #slide 4
  add_slide() %>%
  ph_with(ft, location = ph_location(type = "body")) %>%
  #slide 5
  add_slide() %>%
  ph_with(p2, location = ph_location_type("body")) %>% # create a graph that can be edited
  print(target = paste0(path_out,"example_v1.pptx"))

This code attempts to remove those objects from the deck created:

mypres2 <- read_pptx(paste0(path_out,"example_v1.pptx")) %>%
  on_slide(index = 1) %>% 
  ph_remove(type = "title") %>% 
  ph_remove(type = "ftr") %>%
  ph_remove(type = "dt") %>%
  ph_remove(type = "body") %>%
  on_slide(index = 2) %>% 
  ph_remove(type = "body") %>%
  on_slide(index = 3) %>% 
  ph_remove(type = "body") %>%
  on_slide(index = 4) %>%
  ph_remove(type = "body") %>%
  on_slide(index = 5) %>%
  ph_remove(type = "body") %>%
  print(target = paste0(path_out,"example_v2.pptx"))

Would anyone know of any method that would allow me to remove them without having to manually replace them or generate the deck from scratch again?


Solution

  • ph_remove is removing any kind of existing shape - not only text. I have shorten your example but did try to make it use different types of objects to demo ph_remove. By using new_label in ph_location_type, you can easily create unique labels associated to shape and reuse them later.

    library(flextable)
    library(rvg)
    library(officer)
    library(magrittr)
    library(ggplot2)
    
    path_out <- "."
    
    # prep ggplot
    p1 <- iris %>% 
      ggplot() +
      geom_point(aes(Sepal.Length,Petal.Length,color = Species), size = 3) +
      theme_minimal()
    
    # prep image
    img.file <- file.path(R.home("doc"),"html","logo.jpg")
    
    # prep flextable
    ft <- flextable(head(mtcars)) %>%
      autofit()
    
    # prep editable graph (rvg)
    p2 <- dml(ggobj = p1)
    
    my_pres <- read_pptx() %>%
      #slide 1
      add_slide(layout = "Title and Content", master = "Office Theme") %>%
      ph_with(value = "Hello World", location = ph_location_type(type = "title", newlabel = "ouaoua")) %>% 
      ph_with(value = "A footer", location = ph_location_type(type = "ftr", newlabel = "ouaoui")) %>% 
      ph_with(value = format(Sys.Date()), location = ph_location_type(type = "dt", newlabel = "ouaoue")) %>% 
      ph_with(value = flextable(head(iris)), location = ph_location_type(type = "body", newlabel = "ouaouo")) %>%
      #slide 2
      add_slide() %>%
      ph_with(value = dml(ggobj = p1), location = ph_location_type("body", newlabel = "ouaoua")) %>% 
      print(target = file.path(path_out,"example_v1.pptx"))
    

    enter image description here

    mypres2 <- read_pptx(file.path(path_out,"example_v1.pptx")) %>%
      on_slide(index = 1) %>% 
      ph_remove(ph_label = "ouaoua") %>% 
      ph_remove(ph_label = "ouaoui") %>% 
      ph_remove(ph_label = "ouaoue") %>% 
      ph_remove(ph_label = "ouaouo") %>% 
      on_slide(index = 2) %>% 
      ph_remove(ph_label = "ouaoua") %>%
      print(target = file.path(path_out,"example_v2.pptx"))
    

    enter image description here