This research effort investigated the off-base community to build a tool to identify installations which should explore partnership opportunities. The scope of this research was limited to exploring library partnership opportunities at Air Force installations located in the Continental United States (CONUS). The result of this research is a tool which produces a relative measure for each off-base community, where higher values indicate a greater potential for partnerships. This relative measure utilizes inverse distance weighting (IDW) between an installation and each service location in the surrounding community. The tool can be used by decision makers to compare the computed measures and communities for each installation, and identify where the greatest opportunity for creating a partnership may exist.
Methodology Tab: This section of the app explains the analysis that is utilized. It provides a review of Inverse Distance Weighting (IDW), and how library sizes were estimated.
Analysis Tab: This section of the app presents the results of the IDW analysis. It allows users to investigate the libraries around a specific installation and specified radius. Users can select the installation of interest, define the radius around the installation that should be considered, and select whether straight line distance or driving distances should be used in the analysis.
shiny::includeMarkdown('text.Rmd')
Inverse-Distance-Weighted (IDW) Average
Tobler’s First Law: “All things are related, but nearby things are more related than distant things”
Uses known values to estimate value at nearby points
Library index estimates the value of the libraries surrounding the installation
$$ \begin{equation} \hspace{-700px} \displaystyle Z = \frac{\sum_{i=1}^{n}z_i\times d_i^{-2}}{\sum_{i=1}^{n}d_i^{-2}} \end{equation} $$
Where
$d_i \equiv$ Distance from service to installation
$Z_i \equiv$ Quality of the library (Size)
Collection Space = $13(N_b+N_v+N_a)+(45N_i)$
$N_b \equiv$ Number of books
$N_v \equiv$ Number of serial volumes
$N_a \equiv$ Number of audio visual materials
$N_i \equiv$ Number of internet terminals
Work Space = $150N_w+30N_s/1000$
$N_w \equiv$ Number of workstations
$N_s \equiv$ Number of seats
Library Size = Collection Space + Work Space
absolutePanel(tags$img(src = "IDW.png", height = "600px"), top = "200px", left = "1000px" )
shiny::img(src = "IDW.png", height = "600px", top = "20px", left = "100px" )
library(flexdashboard) library(data.table) library(leaflet) library(DT) IDW_straight <- read.table("App Data/IDW/Straight1.txt", header = TRUE, stringsAsFactors = F) colnames(IDW_straight) <- c("Base Name", "Short Name", "Abbr", "Long", "Lat", "IDW - 5 Miles", "IDW Normalized - 5 Miles", "IDW - 10 Miles", "IDW Normalized - 10 Miles", "IDW - 15 Miles", "IDW Normalized - 15 Miles", "IDW - 20 Miles", "IDW Normalized - 20 Miles", "IDW - 25 Miles", "IDW Normalized - 25 Miles", "IDW - 30 Miles", "IDW Normalized - 30 Miles", "IDW - 35 Miles", "IDW Normalized - 35 Miles", "IDW - 40 Miles", "IDW Normalized - 40 Miles", "IDW - 45 Miles", "IDW Normalized - 45 Miles", "IDW - 50 Miles", "IDW Normalized - 50 Miles", "IDW - 55 Miles", "IDW Normalized - 55 Miles", "IDW - 60 Miles", "IDW Normalized - 60 Miles", "IDW - 65 Miles", "IDW Normalized - 65 Miles", "IDW - 70 Miles", "IDW Normalized - 70 Miles", "IDW - 75 Miles", "IDW Normalized - 75 Miles", "IDW - 80 Miles", "IDW Normalized - 80 Miles", "IDW - 85 Miles", "IDW Normalized - 85 Miles", "IDW - 90 Miles", "IDW Normalized - 90 Miles", "IDW - 95 Miles", "IDW Normalized - 95 Miles", "IDW - 100 Miles", "IDW Normalized - 100 Miles") IDW_drive <- read.table("App Data/IDW/Drive1.txt", header = TRUE, stringsAsFactors = F) colnames(IDW_drive) <- c("Base Name", "Short Name", "Abbr", "Long", "Lat", "IDW - 5 Miles", "IDW Normalized - 5 Miles", "IDW - 10 Miles", "IDW Normalized - 10 Miles", "IDW - 15 Miles", "IDW Normalized - 15 Miles", "IDW - 20 Miles", "IDW Normalized - 20 Miles", "IDW - 25 Miles", "IDW Normalized - 25 Miles", "IDW - 30 Miles", "IDW Normalized - 30 Miles", "IDW - 35 Miles", "IDW Normalized - 35 Miles", "IDW - 40 Miles", "IDW Normalized - 40 Miles", "IDW - 45 Miles", "IDW Normalized - 45 Miles", "IDW - 50 Miles", "IDW Normalized - 50 Miles", "IDW - 55 Miles", "IDW Normalized - 55 Miles", "IDW - 60 Miles", "IDW Normalized - 60 Miles", "IDW - 65 Miles", "IDW Normalized - 65 Miles", "IDW - 70 Miles", "IDW Normalized - 70 Miles", "IDW - 75 Miles", "IDW Normalized - 75 Miles", "IDW - 80 Miles", "IDW Normalized - 80 Miles", "IDW - 85 Miles", "IDW Normalized - 85 Miles", "IDW - 90 Miles", "IDW Normalized - 90 Miles", "IDW - 95 Miles", "IDW Normalized - 95 Miles", "IDW - 100 Miles", "IDW Normalized - 100 Miles") Base_Locs <- read.table("App Data/Base_Locations.txt", header = TRUE, stringsAsFactors = F) Base_Locs <- Base_Locs[-c(2, 19, 21, 28),]
sliderInput(inputId = "rad", label = "Radius Around the Base:", min = 5, max = 100, value = 50, step = 5) selectInput(inputId = "base", label = "Installation:", choices = Base_Locs[,1], selected = NULL) selectInput(inputId = "mode", label = "Distance Mode:", choices = c("Straight Line Distance", "Driving Distance"), selected = NULL)
Inputs:
Radius Around the Base: This input will change the community around the base that is considered. Libraries outside of this radius will not be used in the analysis.
Installation: This input selects the installation that is viewed in the map and library list.
Distance Mode: This changes whether straight line distance or driving distance is used in the analysis.
Panels:
Map: The map provides a visual display of the installation that is selected and the libraries that are within the defined radius.
IDW Measure: The IDW measure is the result produced for a specified radius and distance mode.
Library List: The libraries listed here are the libraries that fall within the specified radius of the selected installation. They are sorted by either straight line distance or driving distance depending on the distance mode selected.
output$basemap <- renderLeaflet({ base.loc <- Base_Locs[which(Base_Locs[,1]%in%input$base),] file.location <- "App Data/Base Libs/" inst <- as.character(input$base) base_lib <- read.table(paste(c(file.location, IDW_straight[which(IDW_straight[, 1] == inst), 3], "_Libs.txt"), collapse = ""), header = TRUE, stringsAsFactors = FALSE) colnames(base_lib) <- c("Library Name", "Service Area Population", "Address", "Latitude", "Longitude", "Central Libraries", "Branch Libraries", "Total Staff", "Print Materials", "Audio Materials", "Video Materials", "Print Serials", "Computers", "Collection Space", "Seats Per", "Work Space", "Size", "Distance", "Weight", "SizeWeight", "Drive Distance", "Drive Weight", "Drive SizeWeight") base_lib <- subset(base_lib, base_lib[, "Distance"] <= input$rad) # redStar <- makeIcon( # iconUrl <- "C:/Files/Documents/R/publicLibs/inst/extdata4/App Data/red_star.png", # iconWidth <- 10, iconHeight <- 40, # iconAnchorX <- 22, iconAnchorY <- 94, # ) leaflet() %>% addTiles() %>% addCircleMarkers(base_lib$Longitude, base_lib$Latitude, color = "blue", radius = 6, fill = T, fillOpacity = 1, opacity = 1, popup = paste(base_lib$`Library Name`, "<br>", base_lib$Address)) %>% addCircleMarkers(base.loc$Longitude, base.loc$Latitude, color = "red", radius = 6, fill = T, fillOpacity = 1, opacity = 1, popup = base.loc$Base..Long.Name.) %>% # addMarkers(base_lib$Longitude, # base_lib$Latitude, # popup = base_lib$Address) %>% # addMarkers(base.loc$Longitude, # base.loc$Latitude, # popup = base.loc$Base..Abbreviation., # icon = redStar) %>% addLegend("bottomleft", title = "Legend", colors = c("Red", "Blue"), labels = c("Air Force Base", "Library"), opacity = 1) }) leafletOutput("basemap", width = "100%", height = "100%")
IDWData <- reactive({ if(input$mode == "Straight Line Distance" ) { CONUS_Locations <- IDW_straight } else { CONUS_Locations <- IDW_drive } IDW <- as.data.table(CONUS_Locations) var <- paste(c("IDW - ", input$rad, " Miles"), collapse = '') IDW <- IDW[order(-IDW[[var]])][,"Overall Rank" := 1:.N] IDW <- as.data.frame(IDW) IDW <- IDW[, c("Base Name", paste(c("IDW - ", as.character(input$rad), " Miles"), collapse = ''), paste(c("IDW Normalized - ", as.character(input$rad), " Miles"), collapse = ''), "Overall Rank")] }) renderTable(IDWData(), digits = 3) # "IDW - 5 Miles", "IDW Normalized - 5 Miles", # IDW <- as.data.table(CONUS_Locations) # var <- paste(input$rad, "Miles") # IDW <- IDW[order(-IDW[[var]])][,"Overall Rank" := 1:.N] # IDW <- as.data.frame(IDW) # IDW <- IDW[, c("Base Name", paste(as.character(input$rad), "Miles"), "Overall Rank")] # paste("Std_", as.character(input$rad), "_Miles")
file.location <- "App Data/Base Libs/" selectedData <- reactive({ inst <- as.character(input$base) base_lib <- read.table(paste(c(file.location, IDW_straight[which(IDW_straight[, 1] == inst), 3], "_Libs.txt"), collapse = ""), header = TRUE, stringsAsFactors = FALSE) colnames(base_lib) <- c("Library Name", "Service Area Population", "Address", "Latitude", "Longitude", "Central Libraries", "Branch Libraries", "Total Staff", "Print Materials", "Audio Materials", "Video Materials", "Print Serials", "Computers", "Collection Space", "Seats Per", "Work Space", "Size", "Distance", "Weight", "SizeWeight", "Drive Distance", "Drive Weight", "Drive SizeWeight") if(input$mode == "Straight Line Distance" ) { col <- c("Library Name", "Service Area Population", "Central Libraries", "Branch Libraries", "Total Staff", "Print Materials", "Audio Materials", "Video Materials", "Print Serials", "Computers", "Collection Space", "Seats Per", "Work Space", "Size", "Distance", "Weight", "SizeWeight") libs_straight <- base_lib[, paste(col)] base_lib.sub <- subset(libs_straight, libs_straight[, "Distance"] <= input$rad) base_lib.sub <- as.data.table(base_lib.sub) base_lib.sub <- base_lib.sub[order(base_lib.sub$Distance)] base_lib.sub <- as.data.frame(base_lib.sub) # var <- paste(input$rad, "Miles") # IDW <- IDW[order(-IDW[[var]])] } else { col <- c("Library Name", "Service Area Population", "Central Libraries", "Branch Libraries", "Total Staff", "Print Materials", "Audio Materials", "Video Materials", "Print Serials", "Computers", "Collection Space", "Seats Per", "Work Space", "Size", "Distance", "Drive Distance", "Drive Weight", "Drive SizeWeight") libs_drive <- base_lib[, paste(col)] base_lib.sub <- subset(libs_drive, libs_drive[, "Distance"] <= input$rad) base_lib.sub <- as.data.table(base_lib.sub) base_lib.sub <- base_lib.sub[order(base_lib.sub$'Drive Distance')] base_lib.sub <- as.data.frame(base_lib.sub) } # datatable(base_lib.sub, rownames = FALSE, extensions = 'Scroller', # options = list(scrollY = 200, scroller = TRUE, columnDefs = list(list(className = 'dt-left', targets = 0:3)))) }) renderTable(selectedData(), digits = 2) ## options=list(scrollX=TRUE, scrolly = TRUE)
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.