Creating multiple Word file reports in a for loop in R Markdown

865 views Asked by At

I'm trying to generate multiple reports automatically with R markdown. I have a MS Word file that I import to R with officer library. In this MS Word file I want to substitute the word alpha with A, B, and C names that I defined in a VarNames vector. I then want to generate report for each of the VarNames in a separate MS Word file. I try to use the code bellow:

library(officer)
library(magrittr)
library(rmarkdown)

my_doc <- read_docx('Word_file.docx')

varNames <- c("A", "B", "C")


for (i in 1:length(varNames)) {
doc2 <- body_replace_all_text(my_doc, old_value = "alpha",new_value = varNames[i], only_at_cursor=FALSE,ignore.case =FALSE);
}
doc2 <- cursor_backward(doc2)
docx_show_chunk(doc2)
my_doc2 <- print(doc2, target ="/Users/majerus/Desktop/R/auto_reporting/my_doc2.docx")

But the code only generates one report for the varname A. Could you please help me figuring out what is wrong with the code? Even if I can generate the report in .pdf or .html formats would be fine. Thanks!

1

There are 1 answers

0
M_Kos On

Ok, so I think the best solution would be this:

# Remember to set your working directory with setwd() accordingly - all reads 
# and writes will be in that dir - or specify the path to the file every time, 
# if you prefer it that way.

# setwd("xyz")

library(officer)

# I think the pipes %>% are very useful, ESPECIALLY with officer, so:
library(dplyr)


# To make it a fully reproductive example, let's create a Word file 
# with only "alpha" text in it.

read_docx() %>%
  body_add_par("alpha") %>%
  print("Word_file.docx")

# now, let's create the vector for the loop to take in

varNames <- c("A", "B", "C")


### Whole docx creation script should be inside the for loop

for (i in 1:length(varNames)) {
  
  #firsty, read the file
  read_docx("Word_file.docx") %>% 
    
    #then, replace the text according to varNames
    body_replace_all_text(old_value = "alpha",
                          new_value = varNames[i], 
                          only_at_cursor=FALSE,
                          ignore.case =FALSE) %>%
    
    # then, print the outputs. Output name should be generated dynamically:
    # every report (for every i) need to have a different name.
    print(target = paste0("Output_",i,".docx")) 

}

# After running your script, in your working directory should be 4 files:
# Word_file.docx "alpha"
# Output_1.docx "A"
# Output_2.docx "B"
# Output_3.docx "C"

Your whole bit with cursor_backward() and docx_show_chunk() seems to be pointless. From my experience - it's best not to use the cursor functionality too much.

Best practice may be to specify in the template the specific places to replace the text (as in your example and my solution) - or just build the whole document dynamically in R (you can firstly load an empty template with predefined styles if you want to use custom ones).