1

I am trying to use officer to add images to a Word document. I have a whole directory's worth of images that I want to loop through. The problem I am having is that I need to add the image to the document, then add the next image to the newly created document that I just created by adding the last image.

Here's a sample of the code without loops or functions:

library(magrittr)
library(officer)
read_docx() %>% # create document
  body_add_img("img1.png", width = 3, height = 4) %>% # add image
  body_add_img("img2.png", width = 3, height = 4) %>% # add image
  body_add_img("img3.png", width = 3, height = 4) %>% # add image
  print(target = "samp.docx") # write document

Using map and lapply doesn't work in this case because every iteration needs to return the object of the previous iteration. I tried writing a function with a for loop but I think I was way off. Any help and pointers would be appreciated.

hmhensen
  • 2,974
  • 3
  • 22
  • 43
  • Look at purrr::reduce? it lets each iteration operate on the output of the previous one. A for loop where you keep adding to the same object should also work. – Calum You Jul 09 '20 at 02:09

2 Answers2

3

I think you can use a reduce here. For example using a bit of purrr

library(purrr)
read_docx() %>% 
  reduce(1:3, function(docx, idx) {
       docx %>% body_add_img(paste0("img", idx, ".png"), width = 3, height = 4)
    }, .init=.) %>%
  print(target = "samp.docx")

The reduce keeps feeding the result back into itself.

MrFlick
  • 195,160
  • 17
  • 277
  • 295
3

I am not sure what was your attempt with the for loop but this simple loop seem to work.

library(officer)
data <- read_docx()
image_list <- paste0('img', 1:3, '.png')

for(i in image_list) {
     data <- body_add_img(data, i, width = 3, height = 4)
}
print(data, target = "samp.docx")
Ronak Shah
  • 377,200
  • 20
  • 156
  • 213