crosstalk: Dynamic filtering for R Markdown
This week, I was pleased to become an official
RStudio Certified Instructor after completing Greg Wilson’s training program, based on his excellent book
Teaching Tech Together. Part of the certification process involved teaching a 10 minute lesson. I chose to create a brief introduction to using the
crosstalk package for dynamic interaction and filtering of plots, maps, and tables.
The primary intent of this post is simply to point out these materials, which are available on GitHub. The lesson teaches the skills needed to create an three-panel application like this (as shown in the screnshot above) with a scatterplot, map, and table comparing ridership at a sample of Chicago train stations in April of 2019 versus 2020 (not long after COVID shutdowns).
To make this more accessible, I converted to previous “lecture” component into a step-by-step tutorial hosted on the repo’s GitHub Pages.1
Not convinced? Let me tell you just a bit more about
crosstalk is, in my opinion, an exciting and underutilized tool for interactive graphics. Shiny is the R world’s go-to tool for creating interactive applications. However, Shiny has a higher learning curve and can be difficult to share with non-R users because it must be deployed on a server.
crosstalk, on the other hand, requires minimal additional syntax and enables browser-based interactions which can be shared in a typical HTML R Markdown output.
This convenience comes at the cost of the feature set.
crosstalk can handle interactive filtering and highlighting across multiple plots, maps, and tables to feature the same data subsets. However, unlike Shiny, t cannot do operations that would require R to recompute the data (for example, aggregation or refitting a model). Arguably, this limitation can also be a strength of
crosstalk; since interaction is limited, the onus still lies firmly on the analyst to find a clear story and think carefully about which relationships to highlight.
Let’s look at an example.
The screenshots above demonstrate the types of exploration that can be done with
crosstalk's dynamic filtering. In the overall scatterplot (above), we see a positive correlation between a higher proportion of weekend (versus weekend) trips in 2019 and lower declines in ridership from 2019 to 2020. This makes sense since business areas have lower weekend travel and would also be more affected by “stay at home” orders. We can use
crosstalk to confirm this theory. Highlight the stations with the greatest decline in trips (left), Chicagoans could quickly recognize the mapped stations to be in the Chicago Loop, the heart of the business district. Conversely, those with the greatest weekend travel and lowest ride decline tend to be located in more residential areas on the west and south sides. (This is, of course, a rather simplistic outcome. I simply use this example to illustrate how the different pieces come together; not to draw any particular conclusion.) You can recreate these exact views in the
demo, as linked above.
If this tutorial peaks your curiosity, check our package developer Carson Sievert’s book Interactive web-based data visualization with R, plotly, and shiny from CRC Press for more information and advanced features.
Initially, I was going to republish the post in it’s entirety, but be warned:
hugodown, which I currently use to render
md, has known issues with including output from
htmlwidgetsR packages (such as
DT) in the Hugo Academic theme that I use. This is not a problem when rendering to normal
rmarkdown::html_outputor apparently when using