bookdown
bookdown copied to clipboard
pass on DT::datatable(caption =) argument, label datatables as tables
I'm relying a lot on DT::datatable()
tables, rather than knitr::kable()
static ones.
Because DT::datatable()
is an htmlwidget
, I seem to be able to set a reference-able, numbered caption only by relying on the knitr chunk option fig.cap =
. (I hope I got this right).
This makes sense for most of the htmlwidgets
, many of which are plots, but, I'd say, not for DT::datatable()
, which is actually a table.
Referencing/captioning it as a figure might be confusing for users.
I've tried several approaches to get a DT::datatable()
to be properly labeled as a table in bookdown::gitbook()
, but without success.
library(DT)
DT::datatable(head(iris), caption = "Table: This is the caption from inside DT")
DT::datatable(head(iris), caption = "(\\#tab:dt-repro) Table: This is the caption from inside DT")
knitr::kable(head(iris), caption = "This is the caption from inside kable")
yield, respectively,
I think it would be nice if I the caption set inside DT::datatable()
could be passed on to bookdown()
in the appropriate way.
Alternatively, and to remain open to more custom tables, I was wondering whether a chunk option tab.cap=
inside knitr might make sense, to be treated analogously to fig.cap =
.
Ps.: This might seem like a somewhat trivial issue (whether an actual table is called a figure), but this gets thornier in use cases where people use DT::datatable()
for HTML-type outputs, and knitr::kable()
for others. In that (my) scenario, the whole numbering and referencing diverges between the different outputs.
I see your point, but I'm afraid I'm not going to deal with this special case. Calling a table a figure is probably not the end of the world (nobody has complained so far that Figure 2.5 is not a figure at https://bookdown.org/yihui/bookdown/html-widgets.html). On the other hand, in non-HTML output, the DT widget will be a screenshot, which is probably qualified as a "figure".
In short, I tend not to make exceptions for DT widgets, but if this issue makes you sleepless at night, I'll be happy to reconsider it when I have time. Thanks!
I agree that having a separate table numbering system for DT tables would be very helpful. In fact, in most of the articles/reports I write, we use separate numbering for Figures and Tables, and therefore using the Figure labelling for tables is not really an option. If you have any other advice, or work-arounds it would be really helpful.
I'll reconsider this issue, but probably not very soon. Thanks!
Thanks for reopening this issue. I think it is an important feature for a robust bookdown. I'm generating a government report using the DT package for dynamic tables. While I understand the argument for calling it a figure in the context of a screen capture for LaTeX, this mis-labeling creates confusion for readers especially if DT and kable tables are intermixed (since the numbering is incremented as if it is a figure). Also, a DT table, labeled as a figure, is likely to raise the ire of communications folks in government that review such things but don't understand the reason behind it being labeled as a figure.
I propose a more general approach. Why not label and increment counters based on the html <div class = "table">
and/or <p class="caption"> (\#tab:myDT)My labeled DT</p>
? This could set up a new counter for any arbitrary class.
I'm more of a scientist than a coder but I'm hoping my explorations helps someone come up with a nifty, efficient solution.
I explored a bunch of things to try to find a work around to get a DT
into a table environment/counter. I used the bookdown-demo and edited the 01-intro.Rmd
file as my MRE.
By setting keep_md: yes
in the _output.yml
file and inspecting the compiled .md
, I note that:
```{r myDT-fig, fig.cap = "my super duper caption", echo = FALSE, message=FALSE, warning=FALSE}
library(DT)
datatable(head(iris))
```
Produces a <div class="figure">
chunk with the DT
widget followed by:
<p class="caption">(\#fig:myDT-fig)my super duper caption</p>
</div>
I pursued this, including:
- Setting chunk hooks to prepend the table reference anchor; and
- Using
htmltools::div
andhtmltools::p
andhtmltools::HTML
to mimic the.md
output generated above.
Using the above techniques (especially htmltools
), I can get output that looks very close to the way fig.cap
and DT
get handled:
```{r myDThtmltools}
library(DT)
library(htmltools)
div(
class = "table",
p(class = "caption", "(\\#tab:myDThtmltools)my caption created using htmltools"),
datatable(head(iris))
)
```
The output (snipped) starts as follows:
<div class="table">
<p class="caption">(\#tab:myDTdiv)my caption created using htmltools</p>
<div id="htmlwidget-365bb828ea197c7c2c1f"
style="width:960px;height:500px;"
class="datatables html-widget">
</div>
The DT widget renders with this at the top:
(\#tab:myDThtmltools)my caption created using htmltools
I'm not sure why this gets parsed differently than a chunk processed with fig.cap
. Maybe an easy solution?
I have found the following workaround for html from https://github.com/rstudio/bookdown/issues/372 After the table produced with DT
library(DT)
datatable(head(iris))
I insert html tag
cat("<table>",paste0("<caption>", "(#tab:mytab)", "caption", " some texte", "</caption>"),"</table>", sep ="\n")
Tab. \@ref(tab:mytab)
which gives a desired output
For latex output, I use knitr tables
I see 4 people posted 👍 ...so the directions are pretty clear...but I'm still a bit confused. If the R markdown looks like this:
---
title: "Untitled"
site: bookdown::bookdown_site
output: bookdown::gitbook
documentclass: book
---
```{r myDThtmltools}
library(DT)
library(htmltools)
div(
class = "table",
p(class = "caption", "(\\#tab:myDThtmltools)my caption created using htmltools"),
datatable(head(iris))
)
```
Tab. \@ref(tab:myDThtmltools)
and then I run:
render_book(input = "test.Rmd")
What would I change to "insert html tag" as described above?
Nevermind - I figured it out 1 minute after posting, I think the solution is this:
---
title: "Untitled"
site: bookdown::bookdown_site
output: bookdown::gitbook
documentclass: book
---
```{r myDThtmltools, results="asis", echo=FALSE}
library(DT)
datatable(head(iris))
cat("<table>",paste0("<caption>", "(#tab:myDThtmltools)", "caption", "Here's my caption", "</caption>"),"</table>", sep ="\n")
```
Tab. \@ref(tab:myDThtmltools)
A small note: If your code chunk name has an underscore, the caption label fails. I have no idea why, but I guess that must mean something else in html.
A small note: If your code chunk name has an underscore, the caption label fails. I have no idea why, but I guess that must mean something else in html.
About this, you can't use _
in chunk name when using referencing mechanism in bookdown. As documented in https://bookdown.org/yihui/rmarkdown/r-code.html we advice to not use underscore
I strongly recommend that you only use alphanumeric characters (a-z, A-Z and 0-9) and dashes (-) in labels, because they are not special characters and will surely work for all output formats. Other characters, spaces and underscores in particular, may cause trouble in certain packages, such as bookdown.
I have found the following workaround for html from #372 After the table produced with DT
library(DT) datatable(head(iris))
I insert html tag
cat("<table>",paste0("<caption>", "(#tab:mytab)", "caption", " some texte", "</caption>"),"</table>", sep ="\n")
Tab. \@ref(tab:mytab)
which gives a desired outputFor latex output, I use knitr tables
Thanks for the solution!
I'm trying this approach, but my caption is being wrapped as if it's being resized to fit a narrow column (I guess it's because it's in a <table>
environment.
Any idea how I can make it fill the entire width of the table that follows?
Thanks, Ido
I managed to fix this by adding a width argument to the table tag <table width=100%>