18

I am using RStudio and knitr to knit .Rmd to .docx

I would like to include inline code in figure captions e.g. something like the following in the chunk options:

fig.cap = "Graph of nrow(data) data points"

However, knitr does not evaluate this code, instead just printing the unevaluated command.

Is there a way to get knitr to evaluate r code in figure/table captions?

Yihui Xie
  • 28,913
  • 23
  • 193
  • 419
TFinch
  • 361
  • 2
  • 9

1 Answers1

25

knitr evaluates chunk options as R code. Therefore, to include a variable value in a figure caption, just compose the required string using paste or sprintf:

fig.cap = paste("Graph of", nrow(data), "data points")

Note that this might be problematic if data is created inside this chunk (and not in a previous chunk) because by default chunk options are evaluated before the chunk itself is evaluated.

To solve this issue, use the package option eval.after to have the option fig.cap be evaluated after the chunk itself has been evaluated:

library(knitr)
opts_knit$set(eval.after = "fig.cap")

Here a complete example:

---
title: "SO"
output: 
  word_document: 
    fig_caption: yes
---


```{r fig.cap = paste("Graph of", nrow(iris), "data points.")}
plot(iris)
```


```{r setup}
library(knitr)
opts_knit$set(eval.after = "fig.cap")
```

```{r fig.cap = paste("Graph of", nrow(data2), "data points.")}
data2 <- data.frame(1:10)
plot(data2)
```

The first figure caption works even without eval.after because the iris dataset is always available (as long as datasets has been attached). Generating the second figure caption would fail without eval.after because data2 does not exist before the last chunk has been evaluated.

CL.
  • 14,577
  • 5
  • 46
  • 73
  • 1
    I want to use colnames() instead, but in my case it would be part of a fig.cap in a chunk with a for loop that outputs a different graph in each iteration. Each graph is representing the first column vs a different column of the same dataframe, being the respective names of the different columns what i want to be shown in the caption of each graph. Is it possible to do this? i tried paste0("graph for",colnames(dataframe)[i]), but the same colname shows in all instances. – ForEverNewbie Nov 15 '20 at 23:36
  • @ForEverNewbie If I understand your problem correctly, you need to skip the `[i]`: try `paste("graph for", colnames(dataframe))`. – CL. Nov 16 '20 at 07:29
  • 1
    that works if the graphs are in the same chunk but executed independently with plot(), but if they are part of a `for` loop, then there is no caption for any of the graphs. A simple exaple of what i mean would be: ```{r chunkname,fig.cap=colnames(mtcars)[1:2]} for(i in 2:3){ plot(mtcars$wt,mtcars[,i]) } ``` – ForEverNewbie Nov 16 '20 at 23:45