Nicholas Hamilton
Nicholas Hamilton

Reputation: 10526

Rmarkdown Chunk Name from Variable

How can I use a variable as the chunk name? I have a child document which gets called a number of times, and I need to advance the chunk labels in such a manner than I can also cross reference them.

Something like this:

child.Rmd

```{r }
if(!exists('existing')) existing <- 0
existing = existing + 1
myChunk <- sprintf("myChunk-%s",existing)
```

## Analysis Routine `r existing`

```{r myChunk,echo = FALSE}
#DO SOMETHING, LIKE PLOT
```

master.Rmd

# Analysis Routines

Analysis for this can be seen in figures \ref{myChunk-1}, \ref{myChunk-2} and \ref{myChunk-3}

```{r child = 'child.Rmd'}
```

```{r child = 'child.Rmd'}
```

```{r child = 'child.Rmd'}
```

EDIT POTENTIAL SOLUTION

Here is one potential workaround, inspired by SQL injection of all things...

child.Rmd

```{r }
if(!exists('existing')) existing <- 0
existing = existing + 1
myChunk <- sprintf("myChunk-%s",existing)
```

## Analysis Routine `r existing`

```{r myChunk,echo = FALSE,fig.cap=sprintf("The Caption}\\label{%s",myChunk)}
#DO SOMETHING, LIKE PLOT
```

Upvotes: 8

Views: 2521

Answers (3)

S J Cowtan
S J Cowtan

Reputation: 374

Dynamic chunk names are possible with knitr::knit_expand(). Arguments are referenced in the child document, including in the chunk headers, using {{arg_name}}.

So my parent doc contains:

```{r child_include, results = "asis"}
###
# Generate a section for each dataset
###
species <- c("a", "b")

out <- lapply(species, function(sp) knitr::knit_expand("child.Rmd"))

res = knitr::knit_child(text = unlist(out), quiet = TRUE)
cat(res, sep = "\n")
```

And my child doc, which has no YAML header, contains:

# EDA for species {{sp}}

```{r getname-{{sp}}}
paste("The species is", "{{sp}}")
```

See here in the RMarkdown cookbook.

Upvotes: 2

dsz
dsz

Reputation: 5212

If you're getting to this level of complexity, I suggest you look at the brew package.

That provides a templating engine where you can dynamically create the Rmd for knitting.

You get to reference R variables in the outer brew environment, and build you dynamic Rmd from there.

Upvotes: 1

chinsoon12
chinsoon12

Reputation: 25225

A suggestion to preknit the Rmd file into another Rmd file before knitting&rendering as follows

master.Rmd:

# Analysis Routines

Analysis for this can be seen in figures `r paste(paste0("\\ref{", CHUNK_NAME, 1:NUM_CHUNKS, "}"), collapse=", ")`

@@@
rmdTxt <- unlist(lapply(1:NUM_CHUNKS, function(n) {
    c(paste0("## Analysis Routine ", n),
        paste0("```{r ",CHUNK_NAME, n, ", child = 'child.Rmd'}"),
        "```")
}))
writeLines(rmdTxt)

@@@

child.Rmd:

```{r,echo = FALSE}
plot(rnorm(100))
```

To knit & render the Rmd:

devtools::install_github("chinsoon12/PreKnitPostHTMLRender")
library(PreKnitPostHTMLRender)   #requires version >= 0.1.1

NUM_CHUNKS <- 5
CHUNK_NAME <- "myChunk-"
preknit_knit_render_postrender("master.Rmd", "test__test.html")

Hope it helps. Cheers!

Upvotes: 2

Related Questions