Reputation: 23
I am producing a rmarkdown document, knitting to PDF and have a figure (figure 1) and a table (table 1) where the table explains the figure in more detail. I have no issue giving either of them a standard caption but I would like to change the table caption to be "Explanation of Figure 1". Is there any way of doing this?
The code chunks are listed below, please let me know if I need to provide more information:
YAML:
- \usepackage{caption} #and several others
output:
bookdown::pdf_document2:
keep_tex: no
latex_engine: xelatex
Code Chunks: Figure 1:
```{r figure-1, fig.cap="Figure"}
ggplot()
```
Table 1:
```{r table, fig.cap="Explanation of Figure \@ref(fig:figure-1)"}
knitr
kableExtra::kable(caption = "Explanation of Figure \@ref(fig:figure-1)")
```
The main error message with one backslash is "Error: '@' is an unrecognized escape in character string" and suggests I forgot to quote character options, which is not true.
With two backslashes the document knits but produces the caption "Explanation of Figure reffig:table"
3 backslashes: the same error as with 1.
4 backslashes: the error is "pandoc-citeproc: reference ref not found. ! Package caption Error: \caption outside float."
Appreciate any suggestions!
Upvotes: 2
Views: 3051
Reputation: 92
Another work around.
Add the following above your chunk:
###### {#your-chunk .unnumbered}
Link header, either using
[text](#your-chunk)
or using the link button in the visual setting of R Studio IDE.
Upvotes: 0
Reputation: 163
J_F referenced Yihui Xie's excellent explanation of using text references in RMarkdown (https://bookdown.org/yihui/bookdown/markdown-extensions-by-bookdown.html#text-references), which you can use for figure and table captions that require more complicated things than plain text (e.g., formatting, cross-references, etc.). This may be a more flexible solution overall than remembering to escape the backslash in Robert's answer, and does not require a workaround with LaTeX.
As Yihui explains, all you need to do is define a text reference on a single line in markdown and reference that in the chunk option "fig.cap" or the "caption" parameter in knitr::kable()
. Just be careful to make sure that each text reference is one paragraph that does not end in a white space.
Here's a basic example.
---
title: "Cross-referencing figures and tables within captions."
output: bookdown::pdf_document2
editor_options:
chunk_output_type: console
---
```{r load-packages}
library(knitr)
library(flextable)
```
(ref:first-fig-caption) Here's a complicated figure caption for the first figure, which can include complicated text styling like $m^2$ and references to other elements in the document, like Table \@ref(tab:mtcars) or Fig. \@ref(fig:cars).
```{r pressure, fig.cap = '(ref:first-fig-caption)'}
plot(pressure)
```
(ref:second-fig-caption) Here's a second complicated figure caption, also referencing Table \@ref(tab:mtcars).
```{r cars, fig.cap = '(ref:second-fig-caption)'}
plot(cars)
```
(ref:caption-table1) A caption for the first table. Check out this cross reference to Fig. \@ref(fig:pressure).
```{r mtcars}
mtcars |>
head() |>
kable(caption = '(ref:caption-table1)')
```
Upvotes: 0
Reputation: 207
Just a workaround, but may helps.
The \\@ref(fig:xxx)
option works well when knitting to a html_document2
.
To me pdf - creation worked fine when using pandoc
in the terminal.
E.g.:
---
title: "Cross ref"
output:
bookdown::html_document2:
collapsed: no
theme: readable
toc: yes
link-citations: yes
---
```{r firstplot, fig.cap = "A plot with points." }
library(ggplot2)
plot_A = ggplot(data = data.frame(x = c(1:10),
y = seq(3, 8, length.out = 10)),
aes(x = x, y =y))+
geom_point()
plot_A
```
Now a second plot with a reference to Fig.: \@ref(fig:firstplot).
```{r secondplot, fig.cap = "This is the same as Fig.: \\@ref(fig:firstplot)
but now with a red line." }
library(ggplot2)
plot_A + geom_line(alpha = .75,col = "red")
```
after knitting just move to the folder containing the html and using pandoc
pandoc mini_ex-crossref.html -o mini_ex.pdf
Upvotes: 1
Reputation: 10352
I tried many different approaches text references, chunk captions, caption argument in the kable function and I´m sure there is a clever solution somewhere, so here is just a workaround with pure Latex.
Add a latex chunk with a label
before the chunk with the figure:
```{=latex}
\begin{figure}
\caption{Figure 1}
\label{Fig-1}
```
```{r figure-1, echo = FALSE}
ggplot(mtcars) +
geom_point(aes(cyl, gear))
```
```{=latex}
\end{figure}
```
Now you can refer to Fig-1
in your latex-caption for the table with normal latex code \ref{Fig-1}
:
```{=latex}
\begin{table}
\caption{Explanation of Figure \ref{Fig-1}}
```
```{r table}
kableExtra::kable(x = mtcars)
```
```{=latex}
\end{table}
```
Notes:
* In my opinion this is just a workaround.
* It´s not possible to use the chunk option fig.cap = ""
and the latex code in parallel
Upvotes: 0