How to create dynamic filtering in data science reports and dashboards?

[This article was first published on Appsilon Data Science - R language, and kindly contributed to R-bloggers]. (You can report issue about the content on this page here)
Want to share your content on R-bloggers? click here if you have a blog, or here if you don't.

R has long ago stopped to be a language only for statistical analysis. It’s also a great tool for communicating the results of data scientist’s work. With RMarkdown and Shiny it’s very easy to quickly design great reports and applications. We want to share few tricks to make your reports and apps more interactive and show you how components can talk to each other.

What is crossfiltering?

Let’s take a look at crossfiltering, which is filtering for coordinated views. Simply by interacting with one component the related element, like chart or table, can update automatically. For example you can zoom a map or select subrange in a plot and get your whole interface reflect that immediately as in Business Intelligence tools.

Htmlwidgets and Crosstalk

First let’s have a look at a crosstalk package that allows us to crossfilter between different htmlwidgets. Currently only available on Github.

We need to install crosstalk:


We use htmlwidgets from leaflet and DT packages that are compatible with crosstalk.


We need developer versions for components to enable crosstalk.

In our example we use marine data for Baltic Sea area that contains ship name, speed and its location (latitude and longitude). We display the ships coordinates on a leaflet map and provide additional information in a DT table. Using the crop button on the map we can filter the data in the table.

Unfortunately table filter does not update dynamically when we navigate map using drag and drop or mouse scroll.

An alternative to crosstalk is robservable an R package that brings observables to htmlwidgets, allowing for shiny-like interactivity in the browser.

Crossfilter in Shiny

In Shiny we can filter table when zooming or changing the area of the map. In order to do that we need to use bounds which are input from the leaflet map. From leaflet R package documentation we know that input$MAPID_bounds provides the latitude/longitude bounds of the currently visible map area. Below we have an example of how to create a coordinated map and table in Shiny. In our case we create a new reactive variable containing filtered data, where we filter latitude and longitude on bounds elements (east, west, north, south). UI of the app is straightforward. Core logic is the dynamic filtering of table where we use reactive value of input$map_bounds.


ships <- read.csv("")

ui <- shinyUI(fluidPage(
    column(6, leaflet::leafletOutput("map")),
    column(6, DT::dataTableOutput("tbl"))

server <- shinyServer(function(input, output) {
  output$map <- leaflet::renderLeaflet({
    leaflet::leaflet(ships) %>%
      leaflet::addTiles() %>% 
  in_bounding_box <- function(data, lat, long, bounds) {
    data %>%
      dplyr::filter(lat > bounds$south & lat < bounds$north & long < bounds$east & long > bounds$west)
  data_map <- reactive({
    if (is.null(input$map_bounds)){
    } else {
      bounds <- input$map_bounds
      in_bounding_box(ships, lat, long, bounds)
  output$tbl <- DT::renderDataTable({
    DT::datatable(data_map(), extensions = "Scroller", style = "bootstrap", class = "compact", width = "100%",
                  options = list(deferRender = TRUE, scrollY = 300, scroller = TRUE, dom = 'tp'))

shinyApp(ui = ui, server = server)


We showed you two simple examples of how to build coordinated leaflet map and DT table in RMarkdown and Shiny. We highly encourage you to try it yourself and also look at more examples available on crosstalk page. Shiny app code used in this example is also available on Github.

To leave a comment for the author, please follow the link and comment on their blog: Appsilon Data Science - R language. offers daily e-mail updates about R news and tutorials about learning R and many other topics. Click here if you're looking to post or find an R/data-science job.
Want to share your content on R-bloggers? click here if you have a blog, or here if you don't.

Never miss an update!
Subscribe to R-bloggers to receive
e-mails with the latest R posts.
(You will not see this message again.)

Click here to close (This popup will not appear again)