#Install Required Packages install.packages(“shiny”)
install.packages(“shinydashboard”)
install.packages(“RSocrata”)
install.packages(“tidyverse”)
install.packages(“leaflet”) # For interactive maps
install.packages(“DT”) # For data tables
library(shiny) library(shinydashboard) library(RSocrata)
library(tidyverse) library(leaflet) library(DT)
api_url <- “https://data.cityofnewyork.us/resource/erm2-nwe9.json”
fetch_311_data <- function(limit = 5000) { url <- paste0(api_url, “?$limit=”, limit) data <- read.socrata(url)
data <- data %>%
mutate(
created_date = as.POSIXct(created_date, format="%Y-%m-%dT%H:%M:%S"),
closed_date = as.POSIXct(closed_date, format="%Y-%m-%dT%H:%M:%S")
) %>%
select(unique_key, created_date, closed_date, complaint_type, borough, latitude, longitude, descriptor, agency) %>%
drop_na(latitude, longitude)
return(data)
}
data_311 <- fetch_311_data()
ui <- dashboardPage( dashboardHeader(title = “NYC 311 Complaints”), dashboardSidebar( sidebarMenu( menuItem(“Dashboard”, tabName = “dashboard”, icon = icon(“dashboard”)), menuItem(“About”, tabName = “about”, icon = icon(“info”)) ) ), dashboardBody( tabItems( tabItem(tabName = “dashboard”, fluidRow( box(width = 4, title = “Filter Data”, status = “primary”, solidHeader = TRUE, selectInput(“complaint_type”, “Complaint Type:”, choices = c(“Select a Type”, unique(data_311\(complaint_type)), selected = "Select a Type", multiple = TRUE), selectInput("borough", "Borough:", choices = c("Select Borough", unique(data_311\)borough)), selected = “Select Borough”, multiple = TRUE), dateRangeInput(“date_range”, “Select Date Range:”, start = min(data_311\(created_date, na.rm = TRUE), end = max(data_311\)created_date, na.rm = TRUE)) ), box(width = 8, title = “Map of Complaints”, status = “primary”, solidHeader = TRUE, leafletOutput(“map”, height = 400) ) ), fluidRow( box(width = 12, title = “Complaints Data Table”, status = “primary”, solidHeader = TRUE, DTOutput(“table”) ) ) ), tabItem(tabName = “about”, h2(“About This Dashboard”), p(“This dashboard visualizes NYC 311 complaints using real-time data.”), p(“Developed for the BIS 412 Advanced Data Visualization course.”) ) ) ) )
server <- function(input, output) { filtered_data <- reactive({ data_311 %>% filter( complaint_type %in% input\(complaint_type, borough %in% input\)borough, created_date >= input\(date_range[1] & created_date <= input\)date_range[2] ) %>% drop_na(longitude, latitude) # Ensure data for map is valid })
output$map <- renderLeaflet({
leaflet(filtered_data()) %>%
addTiles() %>%
addCircleMarkers(
~longitude, ~latitude,
color = "red", radius = 3,
popup = ~paste("<b>Type:</b>", complaint_type, "<br><b>Borough:</b>", borough)
)
})
output$table <- renderDT({
datatable(filtered_data(), options = list(pageLength = 10))
})
}
shinyApp(ui, server)