Search code examples
htmlr-markdownknitr

How to more easily reuse many chunks?


I want to reuse code chunks. It works when I do the following:

# Reusing Code Chunks {.tabset .tabset-pills}

```{r, ref.label='a-chunk-not-in-my-example-1'}
```

## 1st model

```{r, ref.label='a-chunk-not-in-my-example-2'}
```

## 2nd model 

``` {r, ref.label='a-chunk-not-in-my-example-3'}
```

Because I have 100 chunks, this approach is cumbersome.

I have tried using a loop with child documents and knitr::knit_child(), but I have not been able to print the results or a header. I am also aware of knitr::asis_output(), but it does not appear to work in a loop.


Solution

  • If I understand correctly, here is a full example of how you could programmatically reference previous chunks by creating a series of child.Rmd documents and applying knitr::knit_child().

    Basically we cat() all of the desired output from a single chunk with option results='asis'.

    ---
    title: "Programmatically Referencing Chunks"
    output: html_document
    date: "2025-02-14"
    ---
    
    ```{r setup, include=FALSE}
    knitr::opts_chunk$set(echo = FALSE)
    ```
    
    # Original Chunks {.tabset .tabset-pills}
    
    ## Chunk 1
    
    ```{r chunk-1}
    "Chunk 1 contents"
    ```
    
    ## Chunk 2
    
    ```{r chunk-2}
    summary(cars)
    ```
    
    ## Chunk 3
    
    ```{r chunk-3}
    plot(pressure)
    ```
    
    # Referenced Chunks {.tabset .tabset-pills}
    
    ```{r, echo=FALSE, results='asis'}
    # create vector of chunk labels to iterate over
    all_chunk_labels <- knitr::all_labels()
    desired_chunk_labels <- all_chunk_labels[grepl("^chunk", all_chunk_labels)]
    
    for(chunk_label in desired_chunk_labels) {
      # output markdown for header
      cat(paste("## Chunk", sub("chunk-", "", chunk_label)))
    
      # construct child.Rmd using ref.label chunk option
      c(
        sprintf('```{r, ref.label="%s"}', chunk_label),
        '```'
      ) |>
        writeLines("child.Rmd")
      
      # knit child and output results
      res <- knitr::knit_child('child.Rmd', quiet = TRUE)
      cat(res, sep = '\n')
      
      # clean up
      unlink("child.Rmd")
    }
    ```
    

    Reprex files hosted with on GitHub