Search code examples
rshinyshinydashboardjvectormaprmaps

R: creating a route map with multiple filters


~~EDIT~~~

The answer below worked, please see my code to be complete and question answered for anyone who needs the help in the future.

~~~~~~~~

I am trying to create a dashboard in R (first one!) that will create a map that shows thousands of routes taken between the package initial location and the package end location (travelling all over the world). I would then like to have filters in order to show different routes based on criteria (and if possible, give a box to tell how many routes are there based on the selection).

I was able to make the dashboard and the map with all the lines and it looks great. The issue now is I cannot seem to figure out how to create the filters to be interactive. My problem is I am currently creating the lines and plotting them in the For Loop so they are not being saved anywhere.

I have three filters: Department (which I call SBU), Manufacturing plant (which I call Plant and is a sub set of SBU), and Customer.

I.e You can have SBU A with all Plants associated with SBU A and look at Customer Y. You will then see those specific routes associated with this.

I.e. You can have SBU B with Plant K and look at all Customers

Unfortunately, I cannot give out the raw data.

Any help would be greatly appreciated as I am very new to R!

    library(shiny)
    library(shinydashboard)
    library(maps)
    library(geosphere)
    library(maps)
    library(mapproj)
    library(geosphere)
    library(ggrepel)
    library(scales)

    ###########################/ui.R/##################################
    #Setting drive where files are located
    setwd("C:/R Files")

    #Pulling in outside Data Files
    Network <- read.csv("Network Codes.csv")
    Data <- read.csv("Raw Data2.csv")

    #Header
    header <- dashboardHeader(
      title = "Intake Routes")

    #SideBar
    sidebar <- dashboardSidebar(

      #SBU Selection List
      selectInput(inputId = "SBU", "SBU:", selected="ALL",
                  choices = unique(as.character(Network$SBU))),

      #Plant Selection List
      uiOutput("Plant"),

      #Customer Selection List
      selectInput(inputId = "Customer", "Customer:", multiple = TRUE, selected="ALL",
          choices = unique(as.character(Data$Customer.Name.Standard))))

    #Body
    body <- dashboardBody(
      plotOutput(outputId = "map")
    )

    #Builds Dashboard Page
    ui <- dashboardPage(header, sidebar, body)

    ###########################/server.R/###############################
    server <- function(input, output) {

    ##INPUT##  
      #Dependant Plant SideBar List Dependant on SBU
      output$Plant <- renderUI({
        selectInput(inputId = "Plant", "Plant:", multiple = TRUE,
            choices = as.character(Network[Network$SBU == input$SBU, "Plant.Name"]))
      })

      #Reactive data set based on inputs
      Reactive_Data1 <- reactive({
        if (input$SBU == "ALL") {Data}
        else {Data[Data$SBU == input$SBU,]}
      })

      Reactive_Data2 <- reactive({
        if (input$Plant == "ALL") {Reactive_Data1()}
        else {Reactive_Data1()[Reactive_Data1()$Plant == (input$Plant),]}
      })

     Reactive_Data3 <- reactive({
       if (input$Customer == "ALL") {Reactive_Data2()}
       else {Reactive_Data2()[Reactive_Data2()$Customer.Name.Standard == input$Customer,]}
      })

    output$map <- renderPlot({

      #Map coordinates
      xlim <- c(-170,170)
      ylim <- c(-55,75)

      map("world", col="#f2f2f2", fill=TRUE, bg="white", lwd=0.05, xlim=xlim, ylim=ylim)

      npoints <- 20
      nroutes <- nrow(Data)

      for(i in 1:nroutes){

        inter <- gcIntermediate(c(Data$Ship.From.Longitude[i],
                          Data$Ship.From.Latitude[i]),
                        c(Data$Ship.To.Longitude[i],
                          Data$Ship.To.Latitude[i]),
                        n=npoints, addStartEnd = T, breakAtDateLine = T)

        if (is.list(inter)) {
          inter1 <- inter[[1]]
          inter2 <- inter[[2]]
          lines(inter1, col = "green", lwd=0.50)
          lines(inter2, col = "blue", lwd=0.50)}
        else {
          lines(inter, col = "grey", lwd=0.50)}
      }
      })
    }

    #Combines Dashboard and Data together
    shinyApp(ui, server)

Solution

  • You need to make the dataset "reactive" to your inputs and then keep using and referring to that reactive dataset so it updates each time your inputs change.

    Here is an example of making a new reactive variable called reactive_dat based on a filtered version of your Data variable.

    reactive_dat <- reactive({
      Data[Data$SBU == input$SBU, ]
    })