1
votes

I want to create a map that displays traffic KPIs by date and location. The user is able to select a day of traffic with a slider, and a traffic KPI with radio buttons. The data is not showing up on the map.

I have created a reactive object that filters the data based on radio button and slider. The code to render the LeafLet map works outside the app, showing the circles for the data.

The data frame is structured as follows:

date,lat,long,pageviews,unique_visitors
01.01.2019,6.7304,-3.49,206,238
04.01.2019,7.1604,3.35,223,275
07.01.2019,52.25,-4.25,272,407
10.01.2019,46.9757,-123.8095,44,448
13.01.2019,45.4646,-98.468,98,269
16.01.2019,35.1351,-79.432,443,337
19.01.2019,39.5146,-76.173,385,21
22.01.2019,57.1704,-2.08,273,371
25.01.2019,18.2301,42.5001,115,195
28.01.2019,5.32,-4.04,7,27
31.01.2019,32.4543,-99.7384,217,136
03.02.2019,38.923,-97.2251,337,15
06.02.2019,2.7017,33.6761,201,390
09.02.2019,36.7089,-81.9713,177,201
12.02.2019,30.1204,74.29,65,82
15.02.2019,5.4667,-3.2,261,229
18.02.2019,7.1904,1.99,364,38
21.02.2019,3.9837,13.1833,131,74
24.02.2019,-22.7167,-65.7,357,198
27.02.2019,39.4228,-74.4944,297,399
02.03.2019,24.4667,54.3666,382,147
05.03.2019,34.4504,40.9186,8,373
08.03.2019,9.0833,7.5333,83,182
11.03.2019,-9.6954,-65.3597,243,444
14.03.2019,16.85,-99.916,420,29

-> It's stored under "joined" outside of the app (I'm joining two tables) and I call it at the beginning of the pipeline in the reactive object

When I select the date and metric, the output is structured as follows:

lat,long,selected_metric

lat is latitude and long is longitude

I guess the issue is how I'm calling the dataframe in renderLeaflet, as it is a reactive object I'm not sure if the ~ command works to call the columns.

# Required packages
library(shiny)
library(leaflet)
library(dplyr)

# Define UI for application that shows a map
ui <- fluidPage(

    # App title
    titlePanel("Metrics by location"),

    # Input: select date range
    sliderInput("traffic_date",
                "Date:",
                min = as.Date("2019-01-01","%Y-%m-%d"),
                max = as.Date("2019-07-31","%Y-%m-%d"),
                value=as.Date("2019-07-31"),
                timeFormat="%Y-%m-%d"),

    # Input: select metric        
    radioButtons("metric",
                 "Metric",
                 c("Pageviews" = "pageviews", 
                   "Unique Visitors" = "unique_visitors"),
                 selected = "pageviews"),

    # Main panel for Output
    mainPanel(
        # Output: map
        leafletOutput("mymap")
    )
)

# Define server commands to draw map with data
server <- function(input, output) {

    # Reactive expression to generate dataframe for selected date and metric
    d <- reactive({

        day <- input$traffic_date
        show_metric <- input$metric

        d <- joined %>% 
            filter(date == day) %>% 
            select(lat,long,show_metric) %>%
            rename(selected_metric = show_metric)

        })
    # Note: the last pipeline element renames the metric column back to a neutral name

    #create the map
    output$mymap <- renderLeaflet({
        leaflet(d()) %>% 
            addTiles() %>% 
            setView(8.36,46.84,7) %>%
            addCircles(lat = ~ lat, 
                       lng = ~ long, 
                       weight = 1, 
                       radius = ~ selected_metric)
    })
}

# Run app
shinyApp(ui, server)

Currently the code returns an empty map, and I'm not sure which step I'm missing to display the circles.

Thank you for the help!

1
Can you include an example of "joined" to make your code reproducible?Joe
Done! I've included an example of how the data is structured, it's not a direct extract, but the only thing that is different is that in my dataset all coordinates have 7 decimal digitsFlor

1 Answers

1
votes

I think your issue is the use of radius. See below taken from the help documentation:

radius
a numeric vector of radii for the circles; it can also be a one-sided formula, in which case the radius values are derived from the data (units in meters for circles, and pixels for circle markers)

I realised the markers were there they were just really small. Try multiplying the selected_metric by 10000 or changing to use addCircleMarkers.

Update

Using your data set which I converted to date and numeric where applicable and removing setView() so that the map automatically zooms to points out of that range. One of the issues I had was I initially couldn't see points as they were in Africa for example. Also many dates within the range above don't have data to display circles.

# Required packages
library(shiny)
library(leaflet)
library(dplyr)

# Define UI for application that shows a map
ui <- fluidPage(

    # App title
    titlePanel("Metrics by location"),

    # Input: select date range
    sliderInput("traffic_date",
                "Date:",
                min = as.Date("2019-01-01","%Y-%m-%d"),
                max = as.Date("2019-07-31","%Y-%m-%d"),
                value=as.Date("2019-01-01"),
                timeFormat="%Y-%m-%d"),

    # Input: select metric        
    radioButtons("metric",
                 "Metric",
                 c("Pageviews" = "pageviews", 
                   "Unique Visitors" = "unique_visitors"),
                 selected = "pageviews"),

    # Main panel for Output
    mainPanel(
        # Output: map
        leafletOutput("mymap")
    )
)

# Define server commands to draw map with data
server <- function(input, output) {

    # Reactive expression to generate dataframe for selected date and metric
    d <- reactive({

        day <- input$traffic_date
        show_metric <- input$metric

        d <- joined %>% 
            filter(date == day) %>% 
            select(lat,long,show_metric) %>%
            rename(selected_metric = show_metric)

        })
    # Note: the last pipeline element renames the metric column back to a neutral name

    #create the map
    output$mymap <- renderLeaflet({
        leaflet(d()) %>% 
            addTiles() %>% 
            # setView(8.36,46.84,7) %>%
            addCircles(lat = ~ lat, 
                       lng = ~ long, 
                       weight = 1, 
                       radius = ~ selected_metric)
    })
}

# Run app
shinyApp(ui, server)