13

I am using the following template

---
title: "Nice try buddy"
author: "SpaceMan"
date: "13 December 2057"
output:
  bookdown::pdf_document2
header-includes:
- \usepackage{booktabs}
- \usepackage{longtable}
- \usepackage{array}
- \usepackage{multirow}
- \usepackage[table]{xcolor}
- \usepackage{wrapfig}
- \usepackage{float}
- \usepackage{colortbl}
- \usepackage{pdflscape}
- \usepackage{tabu}
- \usepackage{threeparttable}
- \usepackage{threeparttablex}
- \usepackage[normalem]{ulem}
- \usepackage{makecell}  
---
---
references:
- id: fenner2012a
  title: One-click science marketing
  container-title: Nature Materials
  volume: 11
---

```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = TRUE)
```

## Title

\begin{equation}
f\left(k\right)=\binom{n}{k}p^k\left(1-p\right)^{n-k} \label{eq:binom}
\end{equation}

You may refer to it using `\@ref(eq:binom)`, e.g., see Equation \@ref(eq:binom).
and not a nice citation! @fenner2012a


## Including Tables

You can also embed tables, for example:  \@ref(tab:tw)

```{r tw, echo=FALSE}
mytable
```

## References

where mytable is stored in R session and is generated with

mytable <- head(cars) %>% kable(format = "latex", 
                                booktabs = T, 
                                caption = "Demo Table", 
                                escape = F) %>%
kable_styling(latex_options = 'HOLD_position')

Now, this is supposed to work, but when I knit the document using

rmarkdown::render('C:\\Users\\john\\Documents\\bbv.Rmd')

  • the cross-reference for the table is not there! I only see ??
  • and the table has this weird #tab thing - how to get rid of it ?
  • the TOC is here even though I did not ask for it

enter image description here

Any ideas how to fix these issues? Thanks!

EDIT: the weird #tab thing disappeared after a reboot.

ℕʘʘḆḽḘ
  • 18,566
  • 34
  • 128
  • 235
  • 1
    Sorry if my memory is vague since I was dealing with a similar issue 8+ years ago. I think I reran the document 'weaving' twice. In what I can remember, latex, on the first run, creates an index and inserts the values into the document only on the second run. This was outside R, so you may need to do some magic here, e.g. keep the intermediate files when rendering. – Roman Luštrik Sep 23 '18 at 07:01
  • thanks but there has to be a fix using rmarkdown or bookdown.. some weird option or something – ℕʘʘḆḽḘ Sep 23 '18 at 17:57
  • Why did you roll back the changes? Tried to remove a lot of the extra details which weren't relevant to the question – Michael Harper Oct 12 '18 at 18:47
  • @MichaelHarper sorry buddy but you removed way too many things. The question is fine as is, and the screenshot is useful. I appreciate your initiatiive, but leave it be – ℕʘʘḆḽḘ Oct 12 '18 at 18:50
  • What else is relevant? At least remove all the LaTeX packages other than float – Michael Harper Oct 12 '18 at 18:55
  • who cares bro? the question is OK like that frankly. its a nice template for other people to use – ℕʘʘḆḽḘ Oct 12 '18 at 18:56
  • Its just misleading that it's about a very particular issue, not about cross-referencing in general. I'll make sure not to edit your questions in the future :) – Michael Harper Oct 12 '18 at 19:01
  • haha ok lets settle with that tiny revision then – ℕʘʘḆḽḘ Oct 12 '18 at 19:03
  • but please dfirst check that it compiles like in my example when you use `render()` – ℕʘʘḆḽḘ Oct 12 '18 at 19:18
  • sorry bro but these packages are needed for `render` ! – ℕʘʘḆḽḘ Oct 13 '18 at 00:55
  • It rendered fine for me without the added packages (https://imgur.com/8a9EQGR). Potentially one of your packages is out-of-date, but fair enough, revert the question – Michael Harper Oct 13 '18 at 07:12

1 Answers1

6

The problem is that you are working against the intentions of kable by using it outside of an R chunk:

The kable() function will automatically generate a label for a table environment, which is the prefix tab: plus the chunk label.

https://bookdown.org/yihui/bookdown/tables.html

So the following workaround is definitely on the hacky side. Using a file foo.Rmd with

---
output:
  bookdown::pdf_document2:
    toc: no
header-includes:
- \usepackage{float}
---

```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = TRUE)
```


## Including Tables

You can also embed tables, for example:  \@ref(tab:tw)

```{r tw, echo=FALSE}
mytable
```

You can also embed tables, for example:  \@ref(tab:tw2)

```{r tw2, echo=FALSE}
mytable2
```

Referencing images is easier: \@ref(fig:plt)

```{r plt, echo=FALSE, fig.cap = 'hello', fig.height=3} 
myplot 
``` 

one can process this file with a second file foo.R:

library(knitr)
library(kableExtra)
# add the label to the options that would normally be populated from the chunk options
opts_current$append(list(label = "tw"))
mytable <- head(cars) %>% kable(format = "latex", 
                                booktabs = T, 
                                caption = "Demo Table", 
                                escape = F) %>%
  kable_styling(latex_options = 'HOLD_position')
opts_current$restore()

opts_current$append(list(label = "tw2"))
mytable2 <- tail(cars) %>% kable(format = "latex", 
                                booktabs = T, 
                                caption = "Demo Table", 
                                escape = F) %>%
  kable_styling(latex_options = 'HOLD_position')
opts_current$restore()

myplot <- ggplot(cars, aes(x = dist, y = speed)) + geom_point()

rmarkdown::render("foo.Rmd")

In principle, you can do these commands also just at the R prompt, but I try to not use the prompt directly. BTW, I do not get the (#tab) output with your code.

However, I think it makes more sense to not work against the workings of kable. I can understand that it can make sense to separate the data manipulation fro the presentation. However, creating the table is presentation from my point of view. So instead of creating the table externally I would just create the data externally. To make this concrete, let's use a file bar.Rmd:

---
output:
  bookdown::pdf_document2:
    toc: no
header-includes:
- \usepackage{float}
---

```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = TRUE)
library(kableExtra)
```

## Including Tables

You can also embed tables, for example:  \@ref(tab:tw)

```{r tw, echo=FALSE}
mydata %>% kable(format = "latex", 
                 booktabs = T, 
                 caption = "Demo Table", 
                 escape = F) %>%
  kable_styling(latex_options = 'HOLD_position')
```

together with a file bar.R:

# insert data processing here
mydata <- head(cars)
rmarkdown::render("bar.Rmd")

This gives me the same output and the data processing is (initially!) separated from the presentation.

Ralf Stubner
  • 26,263
  • 3
  • 40
  • 75
  • on a side note, rendering indirectly via `render` is really really useful. Embedding my full code into each chunk is really cumbersone and pretty inefficient at the exploratory analysis stage. That is why I am using this. Thanks Ralf! – ℕʘʘḆḽḘ Sep 23 '18 at 20:09
  • also Ralf, do you know how to get rid of the toc? I tried with toc:false without success – ℕʘʘḆḽḘ Sep 23 '18 at 20:29
  • Ralf I cannot get it to work. Where you do you run the `knitr:::opts_current$append(list(label = "label1", label = "label2"))`? In the rmarkdown or in the external R code? – ℕʘʘḆḽḘ Sep 24 '18 at 01:12
  • very nice, thanks. and I guess if I have multiple tables and figures I just keep adding them like `knitr:::opts_current$append(list(label = "label1", label = "label2", label = "label3"))` ? – ℕʘʘḆḽḘ Sep 24 '18 at 12:54
  • ha actually just tried that and it does not work. Should I add the labels one by one with this command? EDIT. yes :) – ℕʘʘḆḽḘ Sep 24 '18 at 12:58
  • EDIT 2. ha actually just tried that and it does not work. that seems to add some extra Table 1 labels in the plot. Should the `opts_current` be reset at some point? I feel the only viable solution might be to run the `kable` line within the chunk, as you suggest in the second part of the answer. Still a good solution though – ℕʘʘḆḽḘ Sep 24 '18 at 13:07
  • @ℕʘʘḆḽḘ See the updated answer. I also found out that `opts_current` isn't internal after all, but I still prefer the second approach. – Ralf Stubner Sep 24 '18 at 13:27
  • thanks Ralf. I actually tried to show a plot in the second case (instead of another table), and the `restore_` trick does not seem to work here. Do you see a way? – ℕʘʘḆḽḘ Sep 24 '18 at 14:32
  • say using `opts_current$append(list(label = "plt"))` where `plt` is ````{r plt, echo=FALSE} myplot ``` ` – ℕʘʘḆḽḘ Sep 24 '18 at 14:33
  • and myplot is simply `myplot <- ggplot(cars, aes(x = dist, y = speed)) + geom_point() ` – ℕʘʘḆḽḘ Sep 24 '18 at 14:34
  • @ℕʘʘḆḽḘ With figures you use the code chunk option `fig.cap` to set the caption, which will also assign the label. all this happens within the Rmd file. – Ralf Stubner Sep 24 '18 at 14:39
  • I just tried that `{r plt, echo=FALSE, fig.cap = 'hello'}` with no success. do you see the `\@ref(tab:plt)` call working for you? – ℕʘʘḆḽḘ Sep 24 '18 at 14:43
  • @ℕʘʘḆḽḘ Works for me. See updated answer. Of course, you have to use the right prefix, i.e. `\@ref(fig:plt)`. – Ralf Stubner Sep 24 '18 at 14:57