library(tidyverse)
library(tidycensus)
library(sf)
library(scales)
library(viridis)
library(knitr)
library(RColorBrewer)
library(knitr)
library(plotly)
Borough boundaries are represented with a shapefile that was downloaded from NYC Open Data.
Census tract boundaries and data are from the 2020 Decennial Census, accessed with the tidyverse R package. Census data includes:
The percentage of people in each racial category for each census tract as well as the percent peole of color were calculated and the census tracts with no residents were removed.
# import population by race for each tract in the Bronx
raw_race_2020 = get_decennial(geography = "tract",
variables=c("P1_001N", "P2_002N", "P2_005N", "P2_006N",
"P2_007N", "P2_008N", "P2_009N", "P2_010N"),
state='NY',
county = 'Bronx',
geometry = TRUE,
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.
######### Create Tidy Data ############
pop20 <- raw_race_2020 |>
rename(pop20 = P1_001N, # !!Total:, universe = RACE
hisp_pop20 = P2_002N, # Hispanic or Latino
black_pop20 = P2_006N, # Not Hispanic or Latino:!!Population of one race:!!Black or African American alone
asian_pop20 = P2_008N, # Not Hispanic or Latino:!!Population of one race:!!Asian alone
white_pop20 = P2_005N) |> # Not Hispanic or Latino:!!Population of one race:!!White alone
mutate(bipoc_pop20 = pop20 - white_pop20,
pct_hisp= round(hisp_pop20/pop20, 3),
pct_white_alone_not_hisp = round(white_pop20/pop20, 3),
pct_black_alone_not_hisp = round(black_pop20/pop20, 3),
pct_asian_alone_not_hisp = round(asian_pop20/pop20, 3),
pct_bipoc_20 = round(bipoc_pop20/pop20, 3)) |>
select(GEOID, NAME, pct_hisp, pct_white_alone_not_hisp, pct_black_alone_not_hisp, pct_asian_alone_not_hisp, pct_bipoc_20)
######### Remove NAs ############
bronx_race <- pop20 |>
mutate(pct_hisp = ifelse(is.nan(pct_hisp), NA, pct_hisp),
pct_white_alone_not_hisp = ifelse(is.nan(pct_white_alone_not_hisp), NA, pct_white_alone_not_hisp),
pct_black_alone_not_hisp = ifelse(is.nan(pct_black_alone_not_hisp), NA, pct_black_alone_not_hisp),
pct_asian_alone_not_hisp = ifelse(is.nan(pct_asian_alone_not_hisp), NA, pct_asian_alone_not_hisp),
pct_bipoc_20 = ifelse(is.nan(pct_bipoc_20), NA, pct_bipoc_20)) |>
separate(NAME, into = c("Tract", "County"), sep = ",")
## Warning: Expected 2 pieces. Additional pieces discarded in 361 rows [1, 2, 3, 4, 5, 6,
## 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, ...].
## import borough shapefiles from NYC Open Data
boros <- st_read("data/raw/geo/Borough Boundaries.geojson")
## import Neighborhood Tabulation Areas for NYC
nabes <- st_read("data/raw/geo/nynta2020.shp")
######### Create summary stats #########
bronx_race_stats <- bronx_race |>
suppressWarnings(summarise(`Census Tract` = Tract,
`Percent Latinx` = percent(pct_hisp),
`Percent White Alone, Not Latinx` = percent(pct_white_alone_not_hisp),
`Percent Black Alone, Not Latinx` = percent(pct_black_alone_not_hisp),
`Percent Asian Alone, Not Latinx` = percent(pct_asian_alone_not_hisp),
`Percent BIPOC` = percent(pct_bipoc_20)))
bronx_race_stats
######### Percent White Map #########
pct_white_map <- ggplot() +
suppressWarnings(geom_sf(lwd = 0,
data = bronx_race,
mapping = aes(fill = pct_white_alone_not_hisp,
text = paste0(Tract,":",
" Percent White ",
percent(pct_white_alone_not_hisp, accuracy=1))))) +
theme_void() +
scale_fill_fermenter(breaks=c(0, .1, .2, .3, .4,.5, .6, .7, .8, .9, 1),
palette = "Blues",
direction = 1,
na.value = "transparent",
name="Percent White Alone (%)",
labels=percent_format(accuracy = 1L)) +
labs(
title = "Bronx, Percent White Alone by Census Tract",
caption = "Source: American Decennial Census, 2020"
) +
geom_sf(data = nabes |> filter(BoroName == "Bronx"),
color = "gray", fill = NA, lwd = 0.25) +
geom_sf(data = boros |> filter(boro_name=="Bronx"), color = "black", fill = NA, lwd = .5)
ggplotly(pct_white_map,tooltip = "text")
######### Percent Latinx Map #########
pct_latinx_map <- ggplot() +
suppressWarnings(geom_sf(lwd = 0,
data = bronx_race,
mapping = aes(fill = pct_hisp,
text = paste0(Tract,":",
" Percent Latinx ",
percent(pct_hisp, accuracy=1))))) +
theme_void() +
scale_fill_fermenter(breaks=c(0, .2, .4, .6, .8, 1),
palette = "Greens",
direction = 1,
na.value = "transparent",
name="Percent Hispanic or Latino (%)",
labels=percent_format(accuracy = 1L)) +
labs(
title = "Bronx, Percent Hispanic or Latino by Census Tract",
caption = "Source: American Decennial Census, 2020"
) +
geom_sf(data = nabes |> filter(BoroName == "Bronx"),
color = "gray", fill = NA, lwd = 0.25) +
geom_sf(data = boros |> filter(boro_name=="Bronx"), color = "black", fill = NA, lwd = .5)
ggplotly(pct_latinx_map,tooltip = "text")
######### Percent Asian Map #########
pct_asian_map <- ggplot() +
suppressWarnings(geom_sf(lwd = 0,
data = bronx_race,
mapping = aes(fill = pct_asian_alone_not_hisp,
text = paste0(Tract,":",
" Percent Asian ",
percent(pct_asian_alone_not_hisp, accuracy=1))))) +
theme_void() +
scale_fill_fermenter(breaks=c(0, .5, .1, .15, .2, .25, .3, .35, .4, .45, .5),
palette = "Oranges",
direction = 1,
na.value = "transparent",
name="Percent Asian Alone (%)",
labels=percent_format(accuracy = 1L)) +
labs(
title = "Bronx, Percent Asian Alone by Census Tract",
caption = "Source: American Decennial Census, 2020"
) +
geom_sf(data = nabes |> filter(BoroName == "Bronx"),
color = "gray", fill = NA, lwd = 0.25) +
geom_sf(data = boros |> filter(boro_name=="Bronx"), color = "black", fill = NA, lwd = .5)
ggplotly(pct_asian_map,tooltip = "text")
######### Percent Black Map #########
pct_black_map <- ggplot() +
suppressWarnings(geom_sf(lwd = 0,
data = bronx_race,
mapping = aes(fill = pct_black_alone_not_hisp,
text = paste0(Tract,":",
" Percent Black ",
percent(pct_black_alone_not_hisp, accuracy=1))))) +
theme_void() +
scale_fill_fermenter(breaks=c(0, .1, .2, .3, .4,.5, .6, .7, .8, .9, 1),
palette = "Purples",
direction = 1,
na.value = "transparent",
name="Percent Black Alone (%)",
labels=percent_format(accuracy = 1L)) +
labs(
title = "Bronx, Percent Black Alone by Census Tract",
caption = "Source: American Decennial Census, 2020"
) +
geom_sf(data = nabes |> filter(BoroName == "Bronx"),
color = "gray", fill = NA, lwd = 0.25) +
geom_sf(data = boros |> filter(boro_name=="Bronx"), color = "black", fill = NA, lwd = .5)
ggplotly(pct_black_map,tooltip = "text")
######### Percent BIPOC Map #########
pct_bipoc_map <- ggplot() +
suppressWarnings(geom_sf(lwd = 0,
data = bronx_race,
mapping = aes(fill = pct_bipoc_20,
text = paste0(Tract,":",
" Percent BIPOC ",
percent(pct_bipoc_20, accuracy=1))))) +
theme_void() +
scale_fill_fermenter(breaks=c(0, .1, .2, .3, .4,.5, .6, .7, .8, .9, 1),
palette = "PuRd",
direction = 1,
na.value = "transparent",
name="Percent BIPOC (%)",
labels=percent_format(accuracy = 1L)) +
labs(
title = "Bronx, People of Color by Census Tract",
caption = "Source: American Decennial Census, 2020"
) +
geom_sf(data = nabes |> filter(BoroName == "Bronx"),
color = "gray", fill = NA, lwd = 0.25) +
geom_sf(data = boros |> filter(boro_name=="Bronx"), color = "black", fill = NA, lwd = .5)
ggplotly(pct_bipoc_map,tooltip = "text")
The maps above show that the Bronx is majority BIPOC, all except for the census tracts in the North West Bronx right by Westchester. The majority of the Hispanic population resides in the south bronx while the Black population is in the North East Bronx census tracts. There is a small asian population in central bronx.