library(tidyverse)
library(tidycensus)
library(sf)
library(scales)
library(viridis)
library(plotly)
library(RColorBrewer)

Methods Section

Mapping the proportion of people with West Indian ancestry in Brooklyn, New York

Borough boundaries are represented with a shapefile that was downloaded from NYC Open Data.

Census tract boundaries and data are from the 2026-18 5-year American Community Survey, accessed with the tidyverse R package. Census data includes:

  • the number of people with West Indian ancestry
  • total population that reports ancestry

The proportion of people with West Indian ancestry for each centure tract was calculated and the cendud tract with no residents were removed.

# load all acs variables
acs201620 <- load_variables(2020, "acs5", cache = T)

## Import table of PEOPLE REPORTING ANCESTRY: B04006
raw_ancestry <- get_acs(geography = "tract", 
                        variables = c(ancestry_pop = "B04006_001",
                                      west_indian = "B04006_094"), 
                        state='NY',
                        county = 'Kings',
                        geometry = T, 
                        year = 2020,
                        output = "wide") 
## Warning: • You have not set a Census API key. Users without a key are limited to 500
## queries per day and may experience performance limitations.
## ℹ For best results, get a Census API key at
## http://api.census.gov/data/key_signup.html and then supply the key to the
## `census_api_key()` function to use it throughout your tidycensus session.
## This warning is displayed once per session.
## import borough shapefiles from NYC Open Data
boros <- st_read("~/Desktop/Parsons/Fall 2024/Urban Ecologies Methods 1/part2/data/raw/geo/Borough Boundaries.geojson")

## import Neighborhood Tabulation Areas for NYC
nabes <- st_read("~/Desktop/Parsons/Fall 2024/Urban Ecologies Methods 1/part2/data/raw/geo/nynta2020_24c/nynta2020.shp")

west_indian <- raw_ancestry |> 
  mutate(pct_west_indian = west_indianE/ancestry_popE)

west_indian <- raw_ancestry |> 
  mutate(pct_west_indian = west_indianE/ancestry_popE,
         pct_west_indian = ifelse(is.nan(pct_west_indian), NA, pct_west_indian)) # if it is not west indian then call it na if not call it west indian 

na_tracts <- west_indian |>
  filter(is.na(pct_west_indian)) # NaN is Not a Number

Results

## Map
west_indian_map <- ggplot() +
  geom_sf(data = west_indian |>
            filter(!is.na(pct_west_indian)), #need to remove nas for ggploty to work
          mapping = aes(fill = pct_west_indian,
                        text = paste0(NAME, ":",
                        "<br>Percent West Indian ancestry: ", #br next line
                        scales::percent(pct_west_indian, accuracy=1))), #scales when you are just using the package
          color = "transparent") + 
  theme_void() +
  scale_fill_distiller(breaks=c(0, .2, .4, .6, .8, 1), 
                       direction = 1,
                       na.value = "#fafafa", #light grey or "transparent"
                       name="Percent West Indian Ancestry (%)",
                       labels=percent_format(accuracy = 1L)) +
  labs(
    title = "Brooklyn, West Indian Ancestry by Census Tract",
    caption = "Source: American Community Survey, 2016-20"
  )+ 
  geom_sf(data = boros |>
            filter(boro_name == "Brooklyn"),
          color = "black", fill = NA, lwd = .5) #line width
## Warning in layer_sf(geom = GeomSf, data = data, mapping = mapping, stat = stat,
## : Ignoring unknown aesthetics: text
ggplotly(west_indian_map, tooltip = "text")
west_indian_2263 <- st_transform(west_indian, 2263) #west indian into the right projection

#remove unnecessary fields in the neighborhood shapefile
nabes_selected <- nabes |>
  select(BoroCode, BoroName, NTA2020, NTAName)


#Perform the spatial join
west_indian_nabes <- west_indian_2263 |>
  st_join(nabes_selected, 
          left = TRUE, #left join
          join = st_intersects, #df
          largest = TRUE) 
## Warning: attribute variables are assumed to be spatially constant throughout
## all geometries

Map boroghs

#Create a map of Crown Heights North, code
ch_west_indian_map <- ggplot() +
  geom_sf(data = west_indian_nabes |> 
          filter(!is.na(pct_west_indian)) |>
          filter(NTAName == "Crown Heights (North)"),
       mapping = aes(fill = pct_west_indian,
                     text = paste0(NAME, ":",
                                   "<br>Percent West Indian ancestry: ",
                                   scales::percent(pct_west_indian, accuracy=1))),
       color = "transparent") + 
  theme_void() +
  scale_fill_distiller(breaks=c(0, .2, .4, .6, .8, 1),
                       direction = 1,
                       na.value = "transparent",
                       name="Percent West Indian Ancestry (%)",
                       labels=percent_format(accuracy = 1L)) +
  labs(
    title = "Crown Heights, West Indian Ancestry by Census Tract",
    caption = "Source: American Community Survey, 2018-22")
## Warning in layer_sf(geom = GeomSf, data = data, mapping = mapping, stat = stat,
## : Ignoring unknown aesthetics: text
  geom_sf(data = nabes |> 
            filter(NTAName == "Crown Heights (North)"),
          color = "black", fill = "transparent", lwd = 0.5)
## [[1]]
## mapping:  
## geom_sf: na.rm = FALSE
## stat_sf: na.rm = FALSE
## position_identity 
## 
## [[2]]
## <ggproto object: Class CoordSf, CoordCartesian, Coord, gg>
##     aspect: function
##     backtransform_range: function
##     clip: on
##     crs: NULL
##     datum: crs
##     default: TRUE
##     default_crs: NULL
##     determine_crs: function
##     distance: function
##     expand: TRUE
##     fixup_graticule_labels: function
##     get_default_crs: function
##     is_free: function
##     is_linear: function
##     label_axes: list
##     label_graticule: 
##     labels: function
##     limits: list
##     lims_method: cross
##     modify_scales: function
##     ndiscr: 100
##     params: list
##     range: function
##     record_bbox: function
##     render_axis_h: function
##     render_axis_v: function
##     render_bg: function
##     render_fg: function
##     setup_data: function
##     setup_layout: function
##     setup_panel_guides: function
##     setup_panel_params: function
##     setup_params: function
##     train_panel_guides: function
##     transform: function
##     super:  <ggproto object: Class CoordSf, CoordCartesian, Coord, gg>
ggplotly(ch_west_indian_map, tooltip = "text")