1
votes

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()
```
1
Try print(htmltools::tagList(DT::datatable(iris))). Looks related to stackoverflow.com/questions/63532652/…stefan
Interesting that adds an empty space where the widget would go between the headings but does not output the widget...Richard J. Acton
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
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 toRichard J. Acton
Yep. Initalising is important to include the JS dependencies in the final HTML document.stefan

1 Answers

2
votes

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