Combining knitted, parameterized RMarkdown chapters in Word

RMarkdown report to Word with parameterized results chapters

I am creating a report in RMarkdown that will consist of some introduction material, then several chapters whose content repeats for each of a set of species. I have to knit the final product to Word. I am aware that this is kind of annoying. Sorry! I must for this task.

So far, my best approach for this has been to render one .docx for the introduction material, then one .docx for each chapter, using a parameterized Rmd file. Each of the chapters contains figures and tables. However, when I combine all the Word docs with the chapters at the end of the document, the indices in the Figure and Table captions update properly (i.e., the figure numbers are sequential from the start), but the in-text citations refer back to chapter 1's figures over and over. I think this is because the parameterized document retains the chapter 1 tag in later chapters (below is what pops up when I right click on an in-text citation label and look at the labels:
image

Maybe a new approach?

I have vacillated between trying child documents, using eval(parse( type statements in r, and this current approach, and I think parameterized reports suit my needs the best, but truly... I will try anything.

To recreate the situation

I have created a repo with a toy example of this here.

  • Clone the repo
  • Run the run.R script
  • in Word, insert the two ParameterizedChapter*.docx chapters into Word using Insert--> Object-->Text from file
  • Update all the fields in the doc (in Windows this is Ctl-A and then F9.

Thank you in advance for your help!

Figure numbering will stay coherent across chapters when you are using a bookdown format for the whole rendering

Considering this, I would not render each doc as its own because you would loose all the book like feature like cross reference

I would use child documents in your different chapter to knit() the .Rmd to .md while considering your variable. Using your parametric Rmd as a template to fill in would also be a solution IMO in combination with child.

Some simple examples to build upon:

Also, new project Quarto could maybe suits you better for such project (https://quarto.org/) it depends really on your parameters (if they are R objects or just values). I doesn't replace R Markdown but extends it for those who needs new features, or don't use R.

There are better project structure , and they have variables (a bit different from R parameters in Rmd though).

Anyway, worth a look maybe.

Hope it helps

Thank you @cderv -- I have investigated both these avenues and was hoping I could get away with using parameterization just because I like the clean approach of being able to loop through chapters. I usually use child documents in my reports, and just wasn't sure how to build child documents in a way that also allowed me to easily set parameter values in an iterative way. I think I can build a solution using knitr::knit_expand() and the {{}} notation. I didn't realize you could use that in chunk names! Game changer. I'll make my new code and post here as solution. Thanks again.

1 Like

Using knitr::knit_expand() and officer::run_reference() I was able to loop through the chapters, keeping the figure numbers and the cross-references straight. I am overjoyed! Here is roughly how I did it (though full code and solution are here in the original repo, if anyone has this issue and is following this thread):

In Parent.Rmd, where I want to paste my chapters in, I have the following code chunk:

cyl.vec <- c(4,6)
src <- list()

for(i in 1:length(cyl.vec)){
  cylcode <- cyl.vec[i]
  src[[i]] <- knitr::knit_expand(here::here('markdown','Template.Rmd'))
}

res = knitr::knit_child(text = unlist(src), quiet = TRUE)
cat(res, sep = '\n')

Then in Template.Rmd, my chapter template, I have the following. There is no yaml header in this file, just Markdown:

# Parameterized report for cars with {{cylcode}} cylinders

Here are some results that repeat for each of several species. Here I will cross-reference to the first figure in this "chapter" (Figure `r officer::run_reference(paste0("first-",{{cylcode}}))`). Here's a reference to the second figure in the chapter  (Figure `r officer::run_reference(paste0("second-",{{cylcode}}))`). The "parse" statement doesn't work with the cross-referencing tag. 

```{r echo=FALSE,fig.cap='First figure in parameterized document -- the figure number is 1 the first time it shows up, and 2 the second time it shows up.', fig.id=paste0("first-",{{cylcode}}),  tab.cap.style = "Figure Caption"}
p1 <- subset(x = mtcars,
                    cyl=={{cylcode}})
plot(p1$mpg,p1$wt,pch=2)

In my opinion, the cool thing about this is that I can create these chapters by essentially looping through the parameters for each, while still preserving the figure and table indices AND the cross-references in the text. It is a life saver! I partially based this solution on this blog post by Thomas de Marchin.

Re: Quarto, I hope we can switch to Quarto for our future reports in this category, but for now the Word output is a crucial step and I have not found graceful ways to use Quarto to make Word docs so far. I do love it though.

1 Like

Awesome ! Thanks for sharing your solution

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.

If you have a query related to it or one of the replies, start a new topic and refer back with a link.