rshinyr-leafletselectinput

Issue with R Shiny, Leaflet --> SelectInput to Change Selection in Drop Down Menu


I am a new R Shiny user and I'm trying to map out all the destinations one can fly to from an origin airport.

I've successfully created a map that displays all the airports of a country when I hard code the country into my code (I've used Italy as an example).

What I want to be able to do is have a "selectinput" that allows a user to select a country and all of the corresponding airports will show up on the map.

Here is my code:

#----------Loading my data----------#
#Dataset 1: Routes
routes=read.csv(url("https://raw.githubusercontent.com/jpatokal/openflights/master/data/routes.dat"))


#Dataset #2: Airports
airports=read.csv(url("https://raw.githubusercontent.com/jpatokal/openflights/master/data/airports-extended.dat"))


#Give Better Names to Columns

colnames(routes)=c("Airline","AirlineID","IATA","SourceAP_ID","DestinationAirport","DestAP_ID","Codeshare","Stops","Equipment")

colnames(airports)=c("AirportID","Name","City","Country","IATA","ICAO","Latitude","Longitude","Altitude","Timezone","DST","TzDatabaseTz","Type","Source")

#Join datasets on Source Airport

fullair=merge(x=routes,y=airports,by="IATA",all.x=TRUE)


#----------Preprocessing Data---------#
fullair2=subset(fullair,fullair$Type=="airport")

fullair2$UniqueID=paste0(fullair2$IATA,"_",fullair2$DestinationAirport)

library(dplyr)
  group_by(IATA) %>%
  mutate(Count=n_distinct(UniqueID)) %>%
  ungroup()
fullair3=as.data.frame(fullair3)


fullair3=fullair3[!duplicated(fullair3[c("UniqueID")]),]

library(rowr)
library(sqldf)
library(RSQLite)



library(stringi)
fullair3$Region=stri_extract(fullair3$TzDatabaseTz, regex='[^/]*')

SpitOutNum=sqldf("select IATA,count(*)
                      from fullair3
                      group by IATA")
SpitOutNum=as.data.frame(SpitOutNum3)
colnames(SpitOutNum)=c("IATA","DestinationCount")
fullair3=merge(x=fullair3,y=SpitOutNum,by="IATA",all.x=TRUE)

#Create the full name
fullair3$NamePart1=paste("(",fullair3$IATA,")",sep ="")
fullair3$FullName=paste(fullair3$Name, fullair3$NamePart1)
fullair3$NamePart1=NULL


#Make destination specific columns like long and lat
SpitOutNum2=sqldf("select IATA, City, Country, Region, Name, DestinationCount, Longitude, 
Latitude
               from fullair3
               group by IATA,City, Country, Region, Name")
colnames(SpitOutNum2)=c("DestinationAirport","DestCity","DestCountry","DestRegion","DestAirportName","DestCount","DestLong","DestLat")
fullair3=merge(x=fullair3,y=SpitOutNum2,by="DestinationAirport",all.x=TRUE)


 #--------------------R Shiny App-------------------#


library(shinydashboard)
library(shiny)
library(leaflet)
library(leaflet.extras)
library(rgdal)
library(sp)
library(raster)

airportchoices=unique(fullair3$FullName)
countrychoices=unique(fullair3$Country)
regionchoices=unique(fullair3$Region)
Italy=subset(fullair3,fullair3$Country=="Italy")


# Define UI for application
ui <- fluidPage(
  dashboardPage(
    dashboardHeader(title="Airport Data"),
dashboardSidebar(
  sidebarMenu(
    menuItem(
      "Maps",
      tabName = "maps",
      icon=icon("globe")
    )
  )
),
dashboardBody(
  tabItems(
    tabItem(
      tabName = "maps",
      tags$style(type="text/css","#all_airports {height:calc(100vh - 80px) !important;}"),
      leafletOutput("all_airports"),
      selectInput(inputId = "countryselect",label="Select a country:",choices=countrychoices)
      
    )
  )
)
  )
)

 # Define server logic 
server <- function(input, output) {


  AirportData=reactive({
    filteredData=subset(fullair3,Country == input$countryselect)
    return(filteredData)
  })


  output$all_airports=renderLeaflet({

    data=AirportData()

    pal=colorNumeric("Reds",Italy$DestinationCount)


    leaflet(data=Italy) %>% 
      addTiles(group="OpenStreetMap")  %>%
  
  
         addCircles(radius = ~Italy$DestinationCount*250, 
             weight = 1, 
             color = "black", 
             fillColor = ~pal(Italy$DestinationCount),
             fillOpacity = 0.7,
             popup = paste0("Airport Name: ", Italy$Name, "<br>",
                            "City: ", Italy$City, "<br>",
                            "Destination Count: ",Italy$DestinationCount,"<br>"
                            ),
             label = ~as.character(Italy$IATA),
             group = "Points") #%>%



      #addMarkers(lng = ~Longitude,lat = ~Latitude, 
       #           popup=~as.character(DestinationCount), 
       #          label=~as.character(DestinationCount), 
       #          group = "Markers")
  })

}

# Run the application 
shinyApp(ui = ui, server = server)

This is my issue:

I'm not sure how to get the selectInput drop down menu to show up on my map and then connect its selection to the map.

How would I change the code above to do that?


Solution

  • You have already done all the necessary work. Just replace all the hard coded Italy to data, which will have the subset of the airport data with the country that the user selects. I'd also consider moving the selectInput to the top of the dashboard as it's hard to scroll from the bottom and users might not see it. I've placed it top center to avoid the dropdown options being covered by the zoom in controls.

    Updated code:

    #----------Loading my data----------#
    #Dataset 1: Routes
    routes=read.csv(url("https://raw.githubusercontent.com/jpatokal/openflights/master/data/routes.dat"))
    
    
    #Dataset #2: Airports
    airports=read.csv(url("https://raw.githubusercontent.com/jpatokal/openflights/master/data/airports-extended.dat"))
    
    
    #Give Better Names to Columns
    
    colnames(routes)=c("Airline","AirlineID","IATA","SourceAP_ID","DestinationAirport","DestAP_ID","Codeshare","Stops","Equipment")
    
    colnames(airports)=c("AirportID","Name","City","Country","IATA","ICAO","Latitude","Longitude","Altitude","Timezone","DST","TzDatabaseTz","Type","Source")
    
    #Join datasets on Source Airport
    
    fullair=merge(x=routes,y=airports,by="IATA",all.x=TRUE)
    
    
    #----------Preprocessing Data---------#
    fullair2=subset(fullair,fullair$Type=="airport")
    
    fullair2$UniqueID=paste0(fullair2$IATA,"_",fullair2$DestinationAirport)
    
    library(dplyr)
    
    fullair3 = fullair2 %>%
      group_by(IATA) %>%
      mutate(Count=n_distinct(UniqueID)) %>%
      ungroup()
    
    fullair3=as.data.frame(fullair3)
    
    
    fullair3=fullair3[!duplicated(fullair3[c("UniqueID")]),]
    
    library(rowr)
    library(sqldf)
    library(RSQLite)
    
    
    
    library(stringi)
    fullair3$Region=stri_extract(fullair3$TzDatabaseTz, regex='[^/]*')
    
    SpitOutNum=sqldf("select IATA,count(*)
                          from fullair3
                          group by IATA")
    
    # SpitOutNum=as.data.frame(SpitOutNum3)
    
    colnames(SpitOutNum)=c("IATA","DestinationCount")
    fullair3=merge(x=fullair3,y=SpitOutNum,by="IATA",all.x=TRUE)
    
    #Create the full name
    fullair3$NamePart1=paste("(",fullair3$IATA,")",sep ="")
    fullair3$FullName=paste(fullair3$Name, fullair3$NamePart1)
    fullair3$NamePart1=NULL
    
    
    #Make destination specific columns like long and lat
    SpitOutNum2=sqldf("select IATA, City, Country, Region, Name, DestinationCount, Longitude, 
    Latitude
                   from fullair3
                   group by IATA,City, Country, Region, Name")
    colnames(SpitOutNum2)=c("DestinationAirport","DestCity","DestCountry","DestRegion","DestAirportName","DestCount","DestLong","DestLat")
    fullair3=merge(x=fullair3,y=SpitOutNum2,by="DestinationAirport",all.x=TRUE)
    
    
    #--------------------R Shiny App-------------------#
    
    
    library(shinydashboard)
    library(shiny)
    library(leaflet)
    library(leaflet.extras)
    library(rgdal)
    library(sp)
    library(raster)
    
    airportchoices=unique(fullair3$FullName)
    countrychoices=unique(fullair3$Country)
    regionchoices=unique(fullair3$Region)
    Italy=subset(fullair3,fullair3$Country=="Italy")
    
    countrychoices <- as.character(countrychoices)
    countrychoices <- sort(countrychoices)
    
    # Define UI for application
    ui <- fluidPage(
      dashboardPage(
        dashboardHeader(title="Airport Data"),
        dashboardSidebar(
          sidebarMenu(
            menuItem(
              "Maps",
              tabName = "maps",
              icon=icon("globe")
            )
          )
        ),
        dashboardBody(
          tabItems(
            tabItem(
              tabName = "maps",
              tags$style(type="text/css","#all_airports {height:calc(100vh - 80px) !important;}"),
    
              fluidRow(column(4),
                       column(8,
                              selectInput(inputId = "countryselect",label="Select a country:",choices=countrychoices, selected = "France")
                              )),
    
              leafletOutput("all_airports")
    
            )
          )
        )
      )
    )
    
    # Define server logic 
    server <- function(input, output) {
    
    
      AirportData=reactive({
        filteredData=subset(fullair3,Country == input$countryselect)
        return(filteredData)
      })
    
    
      output$all_airports=renderLeaflet({
    
        data=AirportData()
    
        pal=colorNumeric("Reds",data$DestinationCount)
    
    
        leaflet(data=data) %>% 
          addTiles(group="OpenStreetMap")  %>%
    
    
          addCircles(radius = ~data$DestinationCount*250, 
                     weight = 1, 
                     color = "black", 
                     fillColor = ~pal(data$DestinationCount),
                     fillOpacity = 0.7,
                     popup = paste0("Airport Name: ", data$Name, "<br>",
                                    "City: ", data$City, "<br>",
                                    "Destination Count: ",data$DestinationCount,"<br>"
                     ),
                     label = ~as.character(data$IATA),
                     group = "Points") #%>%
    
    
    
        #addMarkers(lng = ~Longitude,lat = ~Latitude, 
        #           popup=~as.character(DestinationCount), 
        #          label=~as.character(DestinationCount), 
        #          group = "Markers")
      })
    
    }
    
    # Run the application 
    shinyApp(ui = ui, server = server)
    

    enter image description here