Crosstalk in action
Below is a very simple example from the Crosstalk documentation site. Click and drag to highlight points in the interactive plot (
d3scatter package) and ‘brush’ the map markers (button in upper left) on the interactive map (
leaflet package) and see how selections in each impact each other. Without Crosstalk, selections in one of these widgets would not impact the others.
You can find a more advanced example of Crosstalk in action using Gapminder data. It links HTML widgets from three packages –
DT – and includes a couple of sliders for filtering. All of this in less than 80 lines of code.
Remember all this is happening in the browser and without Shiny. And all you need to do is give each of your widgets a ‘shared data’ object. So instead of this:
data <- readRDS("data/some_data.RDS") # get data datatable(data) # interactive table leaflet(data) %>% addTiles() %>% addMarkers() # map
We can just add one extra line to create the shared data object and pass that to our widgets instead:
data <- readRDS("data/some_data.RDS") shared <- SharedData$new(data) # just add this line datatable(shared) # now refer to the shared data object leaflet(shared) %>% addTiles() %>% addMarkers()
My task: I had to create an app for our users – policy makers – to explore schools data to inform a funding programme. My problem: I didn’t have a server for hosting such an app. In other words, Shiny wasn’t really feasible in this case.
Below are my slides. Click it and hit your left and right arrow keys to navigate. Press ‘p’ to see the presenter notes.
But why stop at one meme? Why not a meme advent calendar counting down the week in advance of the conference?2
I’ve reproduced them here with a bit more context. If you’re on mobile you’ll see the rendered tweets. If on desktop, you’ll need to click the <pic.twitter.com> links in each one.3
Yeah, so I figured that Shiny was the only way to make interactive apps. But I had a problem: no server access for hosting the app. Crosstalk is worth considering in this instance because you can share outputs as HTML files, which will open in the user’s browser.
R users can probably recognise an interactive app made with Shiny4. Probably a Flexdashboard is easy to recognise too; these are typically used for non-interactive dashboard displays, but Crosstalk can be used to blur this line by making the elements interact with each other.
Self-explanatory, really. A small app can be made using Crosstalk and shared freely. Try it!
Day 4 of the GREATEST memes about my #EARL2018 talk - it will be a great Talk. The best! Don't use Crosstalk? SAD. MAKE SHARING SMALL SIMPLE APPS GREAT AGAIN! #trump 🇺🇸 @earlconf pic.twitter.com/oEEzmGCJio— Matt Dray (@mattdray) September 8, 2018
It’s 2018. You’ve got to exploit Trump for personal gain at some point. One potential drawback of Shiny is the need to host the app on a server. Not ideal if you don’t have acces to one. This is not a problem with Crosstalk-enabled tools, which you can share as HTML files.
🚨 day 5 double-meme alert! 🐈🚗 i'm talking #crosstalk for #rstats at #EARL2018. here's some disclaimer memes – i do know crosstalk isn't always a replacement for #shiny! 🙃https://t.co/aKD9oGZATT pic.twitter.com/QhPAmkMZf2— Matt Dray (@mattdray) September 9, 2018
Yeah, so there’s a false equivalency here. Crosstalk doesn’t necessarily help provide a direct replacement for Shiny. You still need Shiny to make ‘proper’ apps. But hey, the picture that the little girl has drawn still looks like a cat, right?
Since everything is rendered in-browser, you’re limited by your browser’s power. This means that the number of points on your interactive map, for example, is limited. In practice it’s maybe a couple of hundred. You can get around this by controlling point layers that can be switched on and off so fewer points are rendered at any one point But that’s a pain.
Let’s say you’ve read your data into the object
data. Ordinarily you would do
DT::datatable(data), etc, to create HTML widgets containing the data. To get the widgets to talk to each other with Crosstalk, you make a shared data object:
shared <- SharedData$new(data). Now you can do
DT::datatable(shared), etc, to get widget interactivity. Only one extra line of code is needed.
Turns out I punked you: my talk is called ‘Crosstalk: Shiny-like without Shiny’ but you can actually put Shiny in your Crosstalk. Why? Your brushing and filtering with Crosstalk can be used to generate Shiny outputs and vice versa. For simplicity, my talk focuses only on Crosstalk.