6

I'm trying to programmatically generate some Rmarkdown and one of the sections contains an HTML widget. These are output fine if they are last in my function. However, if I wrap them in a print so I can put something else after them as you would do for a plot they do not produce any output.

Perhaps this some something to do with the way knitr handles printing i'm not sure. But does anyone know how I can get HTML widgets to behave like plots do in programmatically generated Rmarkdown?

Example .Rmd

---
title: "R Notebook"
output:
  html_document:
    df_print: paged
---

```{r}
ex_plot <- ggplot2::ggplot(iris, ggplot2::aes(Sepal.Length,Sepal.Width)) + 
    ggplot2::geom_point()

gen_rmarkdown_widget_last <- function() {
    cat("# Head 1\n\n")
    DT::datatable(iris)
}

gen_rmarkdown_plots <- function() {
    cat("# Head 1\n\n")
    print(ex_plot)
    cat("# Head 2\n\n")
}

gen_rmarkdown_widgets <- function() {
    cat("# Head 1\n\n")
    print(DT::datatable(iris))

    # tried loading from file
    # tmp <- tempfile()
    # htmlwidgets::saveWidget(DT::datatable(iris), tmp)
    # knitr::include_url(tmp)
    
    # tried a different widget
    # print(plotly::ggplotly(ex_plot))

    cat("# Head 2\n\n")
}

```

```{r, results='asis'}
# works fine
gen_rmarkdown_widget_last()
```

```{r, results='asis'}
# works fine
gen_rmarkdown_plots()
```

```{r, results='asis'}
# Can't have an HTML widget if it is followed by other things
gen_rmarkdown_widgets()
```
Richard J. Acton
  • 885
  • 4
  • 17
  • 1
    Try `print(htmltools::tagList(DT::datatable(iris)))`. Looks related to https://stackoverflow.com/questions/63532652/printing-any-number-of-dataframes-stored-in-list-as-paged-tables-in-rmarkdown/63533860#63533860 – stefan Oct 19 '20 at 15:32
  • Interesting that adds an empty space where the widget would go between the headings but does not output the widget... – Richard J. Acton Oct 19 '20 at 15:48
  • Hm Weird. I tested it on my machine. When I run your code just the headers get printed. Using `print(htmltools::tagList(DT::datatable(iris)))` outputs the DT after Head 1, followed by Head 2. – stefan Oct 19 '20 at 15:51
  • fascinating if I only run the `gen_rmarkdown_widgets` with your suggestion it does not work if I run working example `gen_rmarkdown_widget_last` first then `gen_rmarkdown_widgets` if works. Must be something to do with that initialisation thing mentioned in the post you linked to – Richard J. Acton Oct 19 '20 at 15:56
  • Yep. Initalising is important to include the JS dependencies in the final HTML document. – stefan Oct 19 '20 at 16:04
  • Do you know of a way to 'manually' initialise the widget so that the appropriate JS is included in the document without making a call to DT or other widget that is not 'cached' in the `print`/`tagList` call and thus apparently not noticed by whatever `knitr` is doing to decide what JS to include? – Richard J. Acton Oct 19 '20 at 16:09
  • I mean you can just stick a chunk like this in that seem very hackey: ```{r, include=FALSE, echo=FALSE} DT::datatable(data.frame()) plotly::ggplotly(ggplot2::ggplot()) ``` – Richard J. Acton Oct 19 '20 at 16:20
  • Haven't tried it myself. But I guess you could add some HTML to include the JS dependencies yourself. – stefan Oct 19 '20 at 16:52

1 Answers1

6

The issue has been discussed here.

Adding the dependencies manually is done with:

data.frame() %>%
  DT::datatable() %>%
  knitr::knit_print() %>%
  attr('knit_meta') %>%
  knitr::knit_meta_add() %>%
  invisible()

In the example you provided:

---
title: "R Notebook"
output:
  html_document:
    df_print: paged
---

```{r}
library(dplyr)
#load dependencies
data.frame() %>%
  DT::datatable() %>%
  knitr::knit_print() %>%
  attr('knit_meta') %>%
  knitr::knit_meta_add() %>%
  invisible()

ex_plot <- ggplot2::ggplot(iris, ggplot2::aes(Sepal.Length,Sepal.Width)) + 
    ggplot2::geom_point()



gen_rmarkdown_widget_last <- function() {
    cat("# Head 1\n\n")
    DT::datatable(iris)
}

gen_rmarkdown_plots <- function() {
    cat("# Head 1\n\n")
    print(ex_plot)
    cat("# Head 2\n\n")
}

gen_rmarkdown_widgets <- function() {
    cat("# Head 1\n\n")
    cat(knitr::knit_print(DT::datatable(iris)))
    cat("\n  \n")
    cat("# Head 2\n\n")
}

```


```{r, results='asis'}
gen_rmarkdown_widgets()
```

enter image description here

Waldi
  • 39,242
  • 6
  • 30
  • 78