rknitrr-markdownd3heatmap

Issue plotting multiple d3heatmaps in conditional with knitr


When trying to plot multiple d3heatmaps within a conditional, the HTML that is generated only plots the final heat map. Below is code for an RMD to reproduce the bug.

---
title: "test"
output: html_document
---

This is an R Markdown document. 

```{r}
require(d3heatmap)
myVar = TRUE
if (myVar == TRUE) {
  d3heatmap(mtcars, col = "Spectral")
  d3heatmap(mtcars, col = "Blues")
}
```

If the heat maps are outside of a conditional, multiple will appear in the knitted HTML file. Has anyone else run into this?

sessionInfo()
R version 3.2.3 (2015-12-10)
Platform: x86_64-apple-darwin13.4.0 (64-bit)
Running under: OS X 10.11.3 (El Capitan)

locale:
[1] en_US.UTF-8/en_US.UTF-8/en_US.UTF-8/C/en_US.UTF-8/en_US.UTF-8

attached base packages:
[1] stats     graphics  grDevices utils     datasets  methods   base     

other attached packages:
[1] d3heatmap_0.6.1.1

loaded via a namespace (and not attached):
 [1] htmlwidgets_0.6 magrittr_1.5    htmltools_0.3   tools_3.2.3     base64enc_0.1-3
 [6] yaml_2.1.13     stringi_1.0-1   rmarkdown_0.9.5 knitr_1.12.3    stringr_1.0.0  
[11] digest_0.6.9    evaluate_0.8.3  png_0.1-7  

Solution

  • The underlying issue is explained in this answer by Yihui: HTML widgets "only work when they are generated from top-level R expressions". This explains why wrapping the plots in an if statement doesn't work. The second plot is visible nevertheless because if returns the value of the last expression evaluated, thus "raising" the last plot to the top level.

    As a solution, the plots can be collected in a list and printed via htmltools::tagList as suggested here:

    ```{r}
    require(d3heatmap)
    myVar = TRUE
    res <- list()
    if (myVar == TRUE) {
      res[[1]] <- d3heatmap(mtcars, col = "Spectral")
      res[[2]] <- d3heatmap(mtcars, col = "Blues")
    }
    
    htmltools::tagList(res)
    ```