library(tidyverse)
library(tidycensus)
library(sf)
library(scales)
library(viridis)
library(plotly)
library(RSocrata)
library(readr)
library(ggplot2)
library(knitr)
# Load and transform neighborhood data
raw_nabes <- st_read("~/Desktop/GRAD SCHOO/Year 1/Semester 1/Methods/part2/data/raw/geo/nynta2020_24c/nynta2020.shp") |>
  st_transform(crs = 4326)
# Filter cultural facilities related to "Libraries and Cultural Programs" and create sf object
cultural_facilities <- raw_facilities |>
  filter(FACDOMAIN == "LIBRARIES AND CULTURAL PROGRAMS", LATITUDE > 0, LONGITUDE != 0) |>
  st_as_sf(coords = c("LONGITUDE", "LATITUDE"), crs = 4326, remove = FALSE)
# Perform spatial join between cultural facilities and neighborhood boundaries
cultural_facilities_nabe <- st_join(cultural_facilities, raw_nabes, join = st_intersects)
# Select relevant columns
cultural_facilities_nabe <- cultural_facilities_nabe |>
  select(BORO, NTAName, OPNAME, FACTYPE, FACSUBGRP, FACGROUP, FACDOMAIN, OVERAGENCY, OVERABBREV, OVERLEVEL)
# Summarize the total number of cultural facilities by neighborhood
summary_cultural_facilities_nabe <- cultural_facilities_nabe |>
  group_by(NTAName, BORO) |>
  summarize(total_facilities = n(), .groups = "drop") |>
  arrange(desc(total_facilities))
# Summarize the total number of cultural facilities by borough
summary_cultural_facilities_boro <- summary_cultural_facilities_nabe |>
  st_drop_geometry() |>
  group_by(BORO) |>
  summarize(total_facilities = sum(total_facilities), .groups = "drop") |>
  arrange(desc(total_facilities))

kable(summary_cultural_facilities_boro, 
      col.names = c("Borough", "Total Facilities"), 
      caption = "Cultural Institutions by Borough in NYC", 
      format = "markdown")
Cultural Institutions by Borough in NYC
Borough Total Facilities
MANHATTAN 1284
BROOKLYN 497
QUEENS 256
BRONX 107
STATEN ISLAND 67
# Spatially join summary back to the raw neighborhood boundaries
neighborhoods_with_facilities <- raw_nabes |>
  st_join(summary_cultural_facilities_nabe, join = st_intersects) |>
  mutate(total_facilities = replace_na(total_facilities, 0))
# Plot the map
ggplot(data = neighborhoods_with_facilities) +
  geom_sf(aes(fill = total_facilities), color = "white", size = 0.1) +  # Shade by facility count
  scale_fill_viridis_c(option = "plasma", name = "Cultural Facilities", direction = -1) +  # Use a nice color palette
  theme_minimal() +
  labs(
    title = "Number of Cultural Institutions per Neighborhood in NYC",
    subtitle = "Libraries and Cultural Programs",
    caption = "Source: NYC Open Data"
  ) +
  theme(
    legend.position = "bottom",
    axis.text = element_blank(),  # Remove axis text
    axis.ticks = element_blank(),  # Remove axis ticks
    panel.grid.major = element_blank(),  # Remove major gridlines
    panel.grid.minor = element_blank()   # Remove minor gridlines
  )

LS0tCnRpdGxlOiAiQXNzaWdubWVudCAxMmIiCm91dHB1dDogaHRtbF9ub3RlYm9vawotLS0KCmBgYHtyIHdhcm5pbmc9RkFMU0UsIG1lc3NhZ2U9RkFMU0V9CmxpYnJhcnkodGlkeXZlcnNlKQpsaWJyYXJ5KHRpZHljZW5zdXMpCmxpYnJhcnkoc2YpCmxpYnJhcnkoc2NhbGVzKQpsaWJyYXJ5KHZpcmlkaXMpCmxpYnJhcnkocGxvdGx5KQpsaWJyYXJ5KFJTb2NyYXRhKQpsaWJyYXJ5KHJlYWRyKQpsaWJyYXJ5KGdncGxvdDIpCmxpYnJhcnkoa25pdHIpCmBgYAoKYGBge3Igd2FybmluZz1GQUxTRSwgbWVzc2FnZT1GQUxTRX0KIyBMb2FkIGFuZCB0cmFuc2Zvcm0gbmVpZ2hib3Job29kIGRhdGEKcmF3X25hYmVzIDwtIHN0X3JlYWQoIn4vRGVza3RvcC9HUkFEIFNDSE9PL1llYXIgMS9TZW1lc3RlciAxL01ldGhvZHMvcGFydDIvZGF0YS9yYXcvZ2VvL255bnRhMjAyMF8yNGMvbnludGEyMDIwLnNocCIpIHw+CiAgc3RfdHJhbnNmb3JtKGNycyA9IDQzMjYpCmBgYAoKYGBge3J9CiMgRmlsdGVyIGN1bHR1cmFsIGZhY2lsaXRpZXMgcmVsYXRlZCB0byAiTGlicmFyaWVzIGFuZCBDdWx0dXJhbCBQcm9ncmFtcyIgYW5kIGNyZWF0ZSBzZiBvYmplY3QKY3VsdHVyYWxfZmFjaWxpdGllcyA8LSByYXdfZmFjaWxpdGllcyB8PgogIGZpbHRlcihGQUNET01BSU4gPT0gIkxJQlJBUklFUyBBTkQgQ1VMVFVSQUwgUFJPR1JBTVMiLCBMQVRJVFVERSA+IDAsIExPTkdJVFVERSAhPSAwKSB8PgogIHN0X2FzX3NmKGNvb3JkcyA9IGMoIkxPTkdJVFVERSIsICJMQVRJVFVERSIpLCBjcnMgPSA0MzI2LCByZW1vdmUgPSBGQUxTRSkKYGBgCgpgYGB7cn0KIyBQZXJmb3JtIHNwYXRpYWwgam9pbiBiZXR3ZWVuIGN1bHR1cmFsIGZhY2lsaXRpZXMgYW5kIG5laWdoYm9yaG9vZCBib3VuZGFyaWVzCmN1bHR1cmFsX2ZhY2lsaXRpZXNfbmFiZSA8LSBzdF9qb2luKGN1bHR1cmFsX2ZhY2lsaXRpZXMsIHJhd19uYWJlcywgam9pbiA9IHN0X2ludGVyc2VjdHMpCmBgYAoKYGBge3J9CiMgU2VsZWN0IHJlbGV2YW50IGNvbHVtbnMKY3VsdHVyYWxfZmFjaWxpdGllc19uYWJlIDwtIGN1bHR1cmFsX2ZhY2lsaXRpZXNfbmFiZSB8PgogIHNlbGVjdChCT1JPLCBOVEFOYW1lLCBPUE5BTUUsIEZBQ1RZUEUsIEZBQ1NVQkdSUCwgRkFDR1JPVVAsIEZBQ0RPTUFJTiwgT1ZFUkFHRU5DWSwgT1ZFUkFCQlJFViwgT1ZFUkxFVkVMKQpgYGAKCmBgYHtyfQojIFN1bW1hcml6ZSB0aGUgdG90YWwgbnVtYmVyIG9mIGN1bHR1cmFsIGZhY2lsaXRpZXMgYnkgbmVpZ2hib3Job29kCnN1bW1hcnlfY3VsdHVyYWxfZmFjaWxpdGllc19uYWJlIDwtIGN1bHR1cmFsX2ZhY2lsaXRpZXNfbmFiZSB8PgogIGdyb3VwX2J5KE5UQU5hbWUsIEJPUk8pIHw+CiAgc3VtbWFyaXplKHRvdGFsX2ZhY2lsaXRpZXMgPSBuKCksIC5ncm91cHMgPSAiZHJvcCIpIHw+CiAgYXJyYW5nZShkZXNjKHRvdGFsX2ZhY2lsaXRpZXMpKQpgYGAKCmBgYHtyfQojIFN1bW1hcml6ZSB0aGUgdG90YWwgbnVtYmVyIG9mIGN1bHR1cmFsIGZhY2lsaXRpZXMgYnkgYm9yb3VnaApzdW1tYXJ5X2N1bHR1cmFsX2ZhY2lsaXRpZXNfYm9ybyA8LSBzdW1tYXJ5X2N1bHR1cmFsX2ZhY2lsaXRpZXNfbmFiZSB8PgogIHN0X2Ryb3BfZ2VvbWV0cnkoKSB8PgogIGdyb3VwX2J5KEJPUk8pIHw+CiAgc3VtbWFyaXplKHRvdGFsX2ZhY2lsaXRpZXMgPSBzdW0odG90YWxfZmFjaWxpdGllcyksIC5ncm91cHMgPSAiZHJvcCIpIHw+CiAgYXJyYW5nZShkZXNjKHRvdGFsX2ZhY2lsaXRpZXMpKQoKa2FibGUoc3VtbWFyeV9jdWx0dXJhbF9mYWNpbGl0aWVzX2Jvcm8sIAogICAgICBjb2wubmFtZXMgPSBjKCJCb3JvdWdoIiwgIlRvdGFsIEZhY2lsaXRpZXMiKSwgCiAgICAgIGNhcHRpb24gPSAiQ3VsdHVyYWwgSW5zdGl0dXRpb25zIGJ5IEJvcm91Z2ggaW4gTllDIiwgCiAgICAgIGZvcm1hdCA9ICJtYXJrZG93biIpCmBgYAoKYGBge3J9CiMgU3BhdGlhbGx5IGpvaW4gc3VtbWFyeSBiYWNrIHRvIHRoZSByYXcgbmVpZ2hib3Job29kIGJvdW5kYXJpZXMKbmVpZ2hib3Job29kc193aXRoX2ZhY2lsaXRpZXMgPC0gcmF3X25hYmVzIHw+CiAgc3Rfam9pbihzdW1tYXJ5X2N1bHR1cmFsX2ZhY2lsaXRpZXNfbmFiZSwgam9pbiA9IHN0X2ludGVyc2VjdHMpIHw+CiAgbXV0YXRlKHRvdGFsX2ZhY2lsaXRpZXMgPSByZXBsYWNlX25hKHRvdGFsX2ZhY2lsaXRpZXMsIDApKQoKYGBgCgpgYGB7cn0KIyBQbG90IHRoZSBtYXAKZ2dwbG90KGRhdGEgPSBuZWlnaGJvcmhvb2RzX3dpdGhfZmFjaWxpdGllcykgKwogIGdlb21fc2YoYWVzKGZpbGwgPSB0b3RhbF9mYWNpbGl0aWVzKSwgY29sb3IgPSAid2hpdGUiLCBzaXplID0gMC4xKSArICAjIFNoYWRlIGJ5IGZhY2lsaXR5IGNvdW50CiAgc2NhbGVfZmlsbF92aXJpZGlzX2Mob3B0aW9uID0gInBsYXNtYSIsIG5hbWUgPSAiQ3VsdHVyYWwgRmFjaWxpdGllcyIsIGRpcmVjdGlvbiA9IC0xKSArICAjIFVzZSBhIG5pY2UgY29sb3IgcGFsZXR0ZQogIHRoZW1lX21pbmltYWwoKSArCiAgbGFicygKICAgIHRpdGxlID0gIk51bWJlciBvZiBDdWx0dXJhbCBJbnN0aXR1dGlvbnMgcGVyIE5laWdoYm9yaG9vZCBpbiBOWUMiLAogICAgc3VidGl0bGUgPSAiTGlicmFyaWVzIGFuZCBDdWx0dXJhbCBQcm9ncmFtcyIsCiAgICBjYXB0aW9uID0gIlNvdXJjZTogTllDIE9wZW4gRGF0YSIKICApICsKICB0aGVtZSgKICAgIGxlZ2VuZC5wb3NpdGlvbiA9ICJib3R0b20iLAogICAgYXhpcy50ZXh0ID0gZWxlbWVudF9ibGFuaygpLCAgIyBSZW1vdmUgYXhpcyB0ZXh0CiAgICBheGlzLnRpY2tzID0gZWxlbWVudF9ibGFuaygpLCAgIyBSZW1vdmUgYXhpcyB0aWNrcwogICAgcGFuZWwuZ3JpZC5tYWpvciA9IGVsZW1lbnRfYmxhbmsoKSwgICMgUmVtb3ZlIG1ham9yIGdyaWRsaW5lcwogICAgcGFuZWwuZ3JpZC5taW5vciA9IGVsZW1lbnRfYmxhbmsoKSAgICMgUmVtb3ZlIG1pbm9yIGdyaWRsaW5lcwogICkKYGBgCgo=