published on 31.12.2020
edited on 19.01.2021

I’ve, recently, published a blog post called Perfect Workflow for Publishing Python Notebooks. I tried to explain some of the benefits of using Rmarkdown and reticulate. In this post, I’ll try HTML widgets and explain how we can embed those in our blog post using nothing but R.

knitr::opts_chunk$set(eval = FALSE, echo = TRUE)

Let’s start with basics.

library(MASS)
data(iris)
head(iris)

See, the result is a little different than what you are used to see in RStudio. What we see in the website using the code above, is just text printed out, not even an HTML table. This is not very important for displaying only 6 rows but what if I want to show more? For a better experience, we can use the datatable function from DT library.

DT::datatable(iris, filter="top", options = list(pageLength = 5))

Now, it’s a dataframe with pagination, sort, filter, and search options.

What else we can embed?

A simple example of leaflet:

library(widgetframe)
library(leaflet)
map <- leaflet(height=300) %>%
  addTiles() %>%
  addMarkers(lng=174.768, lat=-36.852, popup="The birthplace of R")
frameWidget(map)

Time-series data with dygraph:

library(dygraphs)
lungDeaths <- cbind(mdeaths, fdeaths)
frameWidget(dygraph(lungDeaths))

Holt-winters example with dygraph & dySeries:

hw <- HoltWinters(ldeaths)
p <- predict(hw, n.ahead = 72, prediction.interval = TRUE)

graph <- dygraph(p, main = "Predicted Lung Deaths (UK)") %>%
  dySeries(c("lwr", "fit", "upr"), label = "Deaths")

frameWidget(graph)

We can also use, plotly to generate interactive plots, xaringan for slides, rbokeh, networkD3 and probably more.

Details

Normally when we use Hugo or any other static site generator, they use some markdown engine to render markdown documents into HTML files. Hugo is using an engine called Goldmark since v0.60.

An R Markdown document is different. An R Markdown document can contain executable code chunks of R, Python, SQL, Bash, and even more programming languages. Hugo (goldmark) can’t render it directly. So, to publish the RMarkdown document on our website, we can generate a markdown file then give it to Hugo’s markdown renderer or convert it directly to HTML. In order to use these widgets, we are going to generate an HTML file directly from the r markdown. The HTML page will include some javascript libraries. Thankfully, all these happen automatically. R Markdown documents get compiled through the packages rmarkdown, bookdown and Pandoc and converted into HTML files. Then Hugo uses these HTML files.

For example, this document’s extension is .Rmd. When I call the blogdown::serve_site() function, blogdown renders through this .Rmd file and generates an HTML file based on the blogdown::html_page output format. It creates all necessary javascript and CSS files into the folder named index_files under the post’s directory.

Trade Offs

  • Using R Markdown can make things slower, compared to plain markdown. Well, isn’t it normal? We are executing the code each time we render the document. It may not affect much though. You should read from here, instead of listening to me.
  • Widgets are not responsive, but we can wrap them with iframes using widgetframe by bhaskarvk.
  • If you are using a custom CSS file instead of a compatible theme from the community, you may get weird results. Wrapping the widget by iframe may also help with that.
  • Don’t forget that you are introducing new javascript files that are overhead.
  • js files under index_files directory will make source code dirty.
  • index_files folder is replicated for each rmarkdown file. There must be a better way to handle these dependencies and share them along with posts yet I couldn’t find any.
  • HTML widgets will not work with .Rmarkdown files, you have to use .Rmd files if you are going to use HTML widgets.

Rmarkdown vs Rmd

Well, they are the same thing. Text files that contain markdown as a markup language and they can contain code chunks. These code chunks get compiled via R. Difference between these two extensions lies in how r packages are treating them. I don’t know if there is any difference for pandoc or knitr but when we are using blogdown; .Rmarkdown generates .markdown while .Rmd generates .html.

So, if we try to use HTML widgets with .Rmarkdown we will get an error saying that “objects that have dependencies (e.g. HTML widgets) do not work when the output format is Markdown instead of HTML.”.

Another difference between these two is that when using .Rmd you’ll need a client-side syntax highlighter like highlight.js. Because blogdown doesn’t use server-side syntax highlighter. On the contrary, you won’t need a client-side highlighter with .Rmarkdown. Because, in the end, it generates .markdown files, and then they are rendered via Hugo. Hugo has a built-in server-side highlighter called Chroma.

Conclusion

In conclusion, we can use HTML widgets in r markdown documents for pretty much everything. You don’t need to know javascript thanks to r packages. You don’t need R runtime once the file is compiled. It should be easy if you are already using these packages and familiar with the R environment. Yet, probably, there will be a learning curve for new comers.

I don’t think I’ll use these widgets. Most of the time, a markdown with plots (as images) should suffice in a blog post. I like to stay close to pure markdown files as much as possible because that way the content will have fewer dependencies.

Update: This was just an experiment for me and maybe a demo for you. I didn’t want to keep the aforementioned “index_files” in the repo. So, I removed them and set the evaluation of all chunks to FALSE. The codes above should work if you try them in your R environment.

You are reading the 2nd of 2 episodes in Rmarkdown.
Published on 31.12.2020 by Mert Bakır. Last update on 19.01.2021 with commit db8d56a.
rmarkdown
#hugo #rmarkdown #rstudio #workflow
published on 10.07.2022

Previously, I’ve published a blog post about deploying static content on heroku with basic authentication. The main purpose was to get basic auth for a freely hosted static website. In that post, we hosted the source code on GitLab and configured a CI/CD pipeline to render the static content …

published on 28.05.2022

Each git commit has a field called Author which consists ‘user.name’ and ‘user.email’. We usually set these variables once, after installing git, with git config --global so that each repo gets the variables from the global definition. We can also set them locally for a …

published on 25.05.2022

In this post, I’ll first walk through hosting static content with basic authentication. Then, we’ll look into deploying to Heroku using GitLab Pipelines, more specifically deploying a certain sub-directory within the project instead of pushing the whole project. Also, I’ll share …

published on 17.04.2022
edited on 15.07.2022

Önceki bölümde, markdown formatını LaTeX formatına dönüştürmek için kullanılan Pandoc yazılımından bahsetmiştik. Şimdi konuyu bir adım daha ileri taşıyıp ve bookdown’a geçiyoruz. Bookdown; Rmarkdown kullanarak teknik dökümanlar, kitaplar yazabilmemizi sağlayan, Yihui Xie tarafından yazılmış …

published on 10.04.2022

I’ve been using WSL-2 on Windows for over a year. It’s very useful because some Python packages are just a headache to install on Windows. Also, docker. It’s just better on Linux. Yet, WSL-2 can also be problematic. I remember trying a dual-boot setup when things just went way too …

published on 03.03.2022

In this post, I’ll share how to install geopandas and some other gis related packages on Windows. If you are on Mac or Linux you can probably just pip install those without any issue. I usually had to do a google search every time I wanted to install these packages on Windows environment. Of …