66 votes

knitr/rmarkdown/Latex : Comment faire des références croisées entre les figures et les tableaux ?

J'essaie de faire des références croisées entre les figures et les tableaux dans un PDF produit avec knitr/rmarkdown. Il y a quelques questions sur SO et tex.stackexchange ( ici et ici par exemple), qui suggèrent que la façon de le faire en ligne est d'ajouter le texte suivant \ref{fig:my_fig}my_fig est l'étiquette du morceau. Cependant, lorsque j'essaie cela dans mon rmarkdown j'obtiens ?? où le numéro de la figure doit être. J'aimerais savoir comment faire pour que les références croisées fonctionnent correctement.

Un exemple reproductible est présenté ci-dessous. Il y a deux fichiers : le rmarkdown plus un header.tex que j'ai inclus juste au cas où cela affecterait la réponse (bien que j'aie le même problème que j'inclue le fichier header.tex ou non).

Dans le rmarkdown Le fichier contient trois exemples de références croisées. L'exemple 1 est une figure pour laquelle la référence croisée échoue ( ?? s'affiche à la place du numéro de la figure). Il y a aussi une deuxième tentative, commentée (basée sur cette réponse SO ), où j'essaie de définir l'environnement de la figure, l'étiquette et la légende avec latex avant et après le chunk, mais cela donne lieu à une pandoc erreur lorsque j'essaie de tricoter le document. L'erreur est la suivante :

! Missing $ inserted.
<inserted text> 
                $
l.108 ![](testCrossRef_

L'exemple 2 utilise xtable et les références croisées fonctionnent. L'exemple 3 utilise kable et les références croisées échouent.

Une capture d'écran de la sortie PDF est incluse au bas de cet article.

rmarkdown fichier

---
title: | 
  | My Title  
author: | 
  | eipi10  
  | Department of Redundancy Department  
date: "`r format(Sys.time(), '%B %e, %Y')`"
output: 
  pdf_document:
    fig_caption: yes
    includes:
      in_header: header.tex
    keep_tex: yes
fontsize: 11pt
geometry: margin=1in
graphics: yes
---

```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = FALSE, message=FALSE, warning=FALSE, fig.height=2, fig.width=4)
```

# Example 1. Figure

This is a report. Take a look at Figure \ref{fig:fig1}.  

```{r fig1, echo=FALSE, fig.cap="This is a caption"}
plot(mtcars$wt, mtcars$mpg)
```

<!-- Now, let's take a look at this other plot in Figure \ref{fig:fig2}. -->

<!-- \begin{figure} -->
<!-- ```{r fig2, echo=FALSE} -->
<!-- plot(mtcars$cyl, mtcars$mpg) -->
<!-- ``` -->
<!-- \caption{This is another caption} -->
<!-- \label{fig:fig2} -->
<!-- \end{figure} -->

# Example 2: `xtable`

Some more text. See Table \ref{tab:tab1} below. 

```{r echo=FALSE, results="asis"}
library(xtable)
print.xtable(
  xtable(mtcars[1:3,1:4], label="tab:tab1", caption="An xtable table"), 
  comment=FALSE)
```

# Example 3: `kable`

Some more text. See Table \ref{tab:tab2} below. 

```{r tab2, echo=FALSE}
library(knitr)
kable(mtcars[1:3,1:4], caption="A `kable` table")
```

header.tex fichier

% Caption on top
% https://tex.stackexchange.com/a/14862/4762
\usepackage{floatrow}
\floatsetup[figure]{capposition=top}
\floatsetup[table]{capposition=top}

Sortie PDF

enter image description here

10 votes

Cette question semble avoir été discutée ici : Je ne peux pas générer \label {fig:mwe-plot} avec knitr . Codage en dur {r fig1, echo=FALSE, fig.cap="\\label{fig:fig1}This is a caption"} semble fonctionner.

48voto

Yihui Points 9906

Vous pouvez utiliser le format de sortie bookdown::pdf_document2 au lieu de pdf_document et la syntaxe pour référencer une figure est la suivante \@ref(fig:chunk-label) ; voir la documentation pour plus de détails : https://bookdown.org/yihui/bookdown/figures.html

3 votes

Existe-t-il un moyen de faire cela qui soit compatible avec la personnalisation de l'application ? rmarkdown des formats, par exemple de rticles des modèles ?

2 votes

@cboettig Oui. Peut-être que je n'ai pas été assez clair : bookdown.org/yihui/bookdown/latexpdf.html Vous pouvez modifier base_format vers n'importe quelle fonction de format de sortie dans n'importe quel paquet.

1 votes

Yihui's réponse ci-dessus ne semble pas fonctionner pour bookdown::tufte_book2. Par exemple, une référence croisée de figure qui apparaît correctement avec pdf_document2 apparaît comme " ??" lorsque le format de sortie est changé en tufte_book2.

40voto

Weihuang Wong Points 9430

Suivant Je ne peux pas générer \label {fig:mwe-plot} avec knitr en ajoutant \label{...} aux arguments de la légende produiront des étiquettes dans le sous-jacent tex c'est-à-dire

```{r fig1, echo=FALSE, fig.cap="\\label{fig:fig1}This is a caption"}
plot(mtcars$wt, mtcars$mpg)
```

et

```{r tab2, echo=FALSE}
library(knitr)
kable(mtcars[1:3,1:4], caption="\\label{tab:tab2}A `kable` table")
```

0 votes

@Yihui, puisque cela est basé sur une Réponse d'un enfant de 2 ans Est-ce que c'est toujours l'état de l'art, ou y a-t-il de meilleures façons de faire maintenant ?

0 votes

Il y a de meilleurs moyens maintenant. En bref, utilisez bookdown::pdf_document2 au lieu de pdf_document ; voir bookdown.org/yihui/bookdown/figures.html

0 votes

Cette solution présente l'avantage de ne pas dépendre de l'ouverture des livres.

3voto

Vous pouvez essayer le sous-titreur paquet. Vous pouvez trouver des exemples dans ce lien .

Dans mon cas, j'inclus un morceau de code avec :

table_captions <- captioner::captioner(prefix="Tab.")
figure_captions <- captioner::captioner(prefix="Fig.")

t.ref <- function(label){
  stringr::str_extract(table_captions(label), "[^:]*")
}

f.ref <- function(label){
  stringr::str_extract(figure_captions(label), "[^:]*")
}

J'inclus des légendes dans les tableaux et les figures lorsque je définis des morceaux de code, comme ceci :

```{r chunk_creating_one_figure, echo=FALSE, fig.cap=figure_captions("one_figure", "figure label")}
plot(1)
```

ou

```{r chunk_creating_one_table, echo=FALSE, fig.cap=table_captions("one_table", "table label")}
knitr::kable(data.frame(col="something"), format="markdown")
```

Les références sont incluses en tant que texte en ligne dans tout mon Rmarkdown avec :

As shown in figure `r f.ref("one_figure")`
Data is shown on table `r t.ref("one_table")`

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X