Я пытаюсь создать интерактивную панель управления, которая позволяет пользователю выбирать аэропорт, а затем на основе этого выбора генерируется карта, показывающая все пункты назначения, в которые можно лететь из выбранного аэропорта с путями, нарисованными над картой.
Вот мой код:
#Load datasets
#Dataset 1: Routes
routes=read.csv(url("https://raw.githubusercontent.com/jpatokal/openflights/master/data/routes.dat"))
dim(routes)
#67662 9
str(routes)
#Dataset #2: Airports
airports=read.csv(url("https://raw.githubusercontent.com/jpatokal/openflights/master/data/airports-extended.dat"))
dim(airports)
#12667 14
#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
#-------------------------------#
#IATA in airports
#SourceAirport in routes (IATA)
fullair=merge(x=routes,y=airports,by="IATA",all.x=TRUE)
dim(routes)
#67662 9
dim(airports)
#12667 14
dim(fullair)
#67662 22
fullair2=subset(fullair,fullair$Type=="airport")
dim(fullair2)
#67467 22
#Clean up dataset
#install.packages("dplyr")
library(dplyr)
#Make a new unique ID by combining IATA and Destination Airport
fullair2$UniqueID=paste0(fullair2$IATA,"_",fullair2$DestinationAirport)
head(fullair2$UniqueID)
length(unique(fullair2$UniqueID))
#37445
#Create column that assigns number of unique routes to single airport
fullair3=fullair2 %>%
group_by(IATA) %>%
mutate(Count=n_distinct(UniqueID)) %>%
ungroup()
fullair3=as.data.frame(fullair3)
#Get rid of duplicates
fullair3=fullair3[!duplicated(fullair3[c("UniqueID")]),]
dim(fullair3)
#37445 10
library(rowr)
library(sqldf)
library(RSQLite)
#-------------------Grab Region and/or Country-------------------#
library(stringi)
fullair3$Region=stri_extract(fullair3$TzDatabaseTz, regex='[^/]*')
unique(fullair3$Region)
table(fullair3$Region)
#-----------Number of Routes from Destination------------#
SpitOutNum=sqldf("select IATA,count(*)
from fullair3
group by IATA")
SpitOutNum=as.data.frame(SpitOutNum)
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
fullair3$Name2Part1=paste("(",fullair3$DestinationAirport,")",sep ="")
fullair3$DestFullName=paste(fullair3$DestAirportName, fullair3$Name2Part1)
#Make destination columns
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)
fullair3$Name2Part1=paste("(",fullair3$DestinationAirport,")",sep ="")
fullair3$DestFullName=paste(fullair3$DestAirportName, fullair3$Name2Part1)
#TABLE1 - Region
table1=sqldf("select Region, FullName as 'Airport Name', Country, City, count(*) as 'Number of Routes'
from fullair3
group by Region, FullName, Country, City
order by count(*) desc")
#TABLE2 - Country
table2=sqldf("select Country, FullName as 'Airport Name', City, count(*) as 'Number of Routes'
from fullair3
group by Country, FullName, City
order by count(*) desc")
#TABLE3 - Destination
table3=sqldf("select FullName, DestFullName as 'Airport Name', DestCountry as 'Country',DestCity as 'City', DestCount as 'Number of Routes'
from fullair3
group by FullName, DestFullName, DestCountry, DestCity
order by DestCount desc")
#TABLE 4 - ALL DATA
table4=sqldf("select FullName as 'Airport Name', Country, City, count(*) as 'Number of Routes'
from fullair3
group by FullName, Country, City
order by count(*) desc")
#----------PART 2: SHINY DASHBOARD----------#
library(shinydashboard)
library(shiny)
library(leaflet)
library(leaflet.extras)
library(rgdal)
library(sp)
library(raster)
library(DT)
library(markdown)
airportchoices=unique(fullair3$FullName)
# Define UI for application
ui <- fluidPage(
dashboardPage(
dashboardHeader(title="Airport Accessibility Analysis"),
dashboardSidebar(
sidebarMenu(
menuItem("All Data",
tabName = "AllData",
icon=icon("table")
),
menuItem("Destination Maps",
tabName = "DestMaps",
icon=icon("plane-arrival")
))
),
dashboardBody(
tabItems(
tabItem(
tabName = "AllData",
DTOutput("alldata")
),
tabItem(
tabName = "DestMaps",
fluidRow(column(4),
column(8, selectInput(inputId = "destselect",label="Select an airport:",choices=airportchoices)
)),
DTOutput("destdata"),
leafletOutput("dest_airports")
)
)
)
)
)
# Define server logic
server <- function(input, output) {
#----------DESTINATION FILTERING---------#
AirportData=reactive({
filteredData=subset(fullair3, FullName == input$destselect)
return(filteredData)
})
AirportDataTable=reactive({
filteredDataTable=subset(table3,FullName==input$destselect)
filteredDataTable$FullName=NULL
return(filteredDataTable)
})
#----------ALL DATA TABLE----------#
output$alldata=renderDT({
datatable(table4,options=list(pageLength=10,
lengthMenu=c(10,15,20,25)
),rownames = FALSE)
})
#-------------------DESTINATION PLOTS-------------------#
output$destdata=renderDT({
data_table = AirportDataTable()
datatable(data_table,options=list(pageLength=5,
lengthMenu=c(5,10,15,20)
),rownames = FALSE)
})
output$dest_airports=renderLeaflet({
data=AirportData()
pal=colorNumeric("Yellow",data$DestCount)
curved.lines2 =
gcIntermediate(
p1 = as.matrix(x = data[,c("Longitude","Latitude")] ),
p2 = as.matrix(x = data[,c("DestLong","DestLat")] ),
breakAtDateLine = TRUE,
n = 1000,
addStartEnd = TRUE,
sp = TRUE)
leaflet(data=data) %>%
addTiles(group="Esri.WorldImagery") %>%
addProviderTiles(providers$Esri.WorldImagery,
options = tileOptions(minZoom =0, maxZoom = 6),
group = "Esri.WorldImagery") %>%
addProviderTiles(providers$CartoDB.DarkMatter,
options = tileOptions(minZoom =0, maxZoom = 6),
group = "CartoDB.DarkMatter") %>%
addCircleMarkers(lng = ~data$Longitude,
lat = ~data$Latitude,
radius = 2,
color = "red",
label = paste(data$FullName)) %>%
addCircleMarkers(lng = data$DestLong,
lat = data$DestLat,
radius = ~data$DestCount/25,
color="yellow",
weight = 1,
popup = paste0("Airport Name: ", data$DestAirportName, "<br>",
"City: ", data$DestCity, "<br>",
"Destination Count: ",data$DestCount,"<br>"
),
label = ~as.character(data$DestinationAirport),
group = "Points") %>%
addPolylines( data = curved.lines2
, weight = 1
) %>%
addLayersControl(
baseGroups = c("Esri.WorldImagery","CartoDB.DarkMatter"),
options = layersControlOptions(collapsed = TRUE)
)
})
}
# Run the application
shinyApp(ui = ui, server = server)
Всякий раз, когда я запускаю этот код, я получаю инструментальную панель, которая отображается так, как я хотел, с динамически меняющимися таблицами и картами. Однако для некоторых выборов аэропортов я получаю сообщение об ошибке. Например, когда я выбираю «Аэропорт Эс-Сения (ORN)», я получаю только таблицу без карты, а также сообщение об ошибке, которое гласит: «Ошибка: отсутствует значение там, где необходимо ИСТИНА / ЛОЖЬ».
Проверяя консоль R, я получаю предупреждение:
Warning: Error in if: missing value where TRUE/FALSE needed
97: .interm
96: gcIntermediate
95: func [/Users/myname/Desktop/FolderName/app.R#323]
82: origRenderFunc
81: output$dest_airports
1: runApp
Вот мои проблемы:
1.) Я не понимаю, почему это работает для некоторые варианты, а не другие
2.) Как решить эту проблему с помощью gcIntermediate
Может ли кто-нибудь помочь мне диагностировать ошибку моего кода? Я чувствую, что я действительно близко, и решение может быть просто одна маленькая вещь. Любая помощь будет оценена! Спасибо!