Mapping race across New York City

library(tidyverse)
library(tidycensus)
library(scales)
library(viridis)
library(dplyr)
library(sf)

Methods

Purpose: Understand concentrations of population by race in New York City

Data sources:

Methods:

raw_NYC_race_2020 = get_decennial(geography = "tract", 
                              variables=c(total_pop = "P1_001N",
                                          hispanic = "P2_002N",
                                          white = "P2_005N",
                                          black = "P2_006N",
                                          asian = "P2_008N"),
                              state='NY',
                              county=c("Bronx", "Kings", "New York", "Queens", "Richmond"),
                              geometry = TRUE, 
                              year = 2020,
                              output = "wide")
NYC_race_2020 <- raw_NYC_race_2020 %>% 
  mutate(pct_hispanic = round(hispanic/total_pop, 3),
         pct_white = round(white/total_pop, 3),
         pct_black = round(black/total_pop, 3),
         pct_asian = round(asian/total_pop, 3)) %>% 
  separate(NAME, into = c("tract", "county", "state"), sep = ", ") 

Results

county_race_summary <- NYC_race_2020 %>%
  group_by(county) %>%
  summarize(
    total_population = sum(total_pop, na.rm = TRUE),
    total_hispanic = sum(hispanic, na.rm = TRUE),
    total_white = sum(white, na.rm = TRUE),
    total_black = sum(black, na.rm = TRUE),
    total_asian = sum(asian, na.rm = TRUE),
    pct_hispanic = paste0(round((total_hispanic / total_population) * 100, 1), "%"),
    pct_white = paste0(round((total_white / total_population) * 100, 1), "%"),
    pct_black = paste0(round((total_black / total_population) * 100, 1), "%"),
    pct_asian = paste0(round((total_asian / total_population) * 100, 1), "%"),
    .groups = "drop"
  )

print(county_race_summary)
Simple feature collection with 5 features and 10 fields
Geometry type: GEOMETRY
Dimension:     XY
Bounding box:  xmin: -74.25563 ymin: 40.4961 xmax: -73.70036 ymax: 40.91771
Geodetic CRS:  NAD83

The data shows that New York City neighborhoods are still meaningfully segregated by race.

At the borough level, the Bronx is predominantly Hispanic (54%) and Black (29%), while Manhattan is predominantly white (47%) and Hispanic (24%). Staten Island has a high portion of white residents (56%), while Queens is more diverse, with 28% Hispanic, 27% Asian, 23% White, and 16% Black. Finally, Brooklyn has large concentrations of White residents (35%) and Black residents (27%), with a smaller, but still meaningful portion of Hispanic (19%) and Asian (14%) residents.

st_crs(NYC_race_2020)
st_crs(boros)
nyc_race_2263 <- st_transform(NYC_race_2020, 2263)
boros_2263 <- st_transform(boros, 2263)
# Map Hispanic Population by cenus track
ggplot(data = nyc_race_2263, mapping = aes(fill = pct_hispanic))  + 
  geom_sf(color = "#ffffff", 
          lwd = 0) + # removes the census tract outline
  theme_void() +
  scale_fill_distiller(palette = "Blues",
                       breaks=c(0, .2, .4, .6, .8, 1),
                       direction = 1,
                       na.value = "transparent",
                       name="Percent Hispanic (%)",
                       labels=percent_format(accuracy = 1L)) +
  labs(
    title = "Hispanic or Latinx population in NYC by Census Tract",
    caption = "Source: Decennial Census, 2020"
  ) + 
  geom_sf(data = boros_2263, color = "black", fill = NA, lwd = .2)


# Map Black population by census tract
ggplot(data = nyc_race_2263, mapping = aes(fill = pct_black))  + 
  geom_sf(color = "#ffffff", 
          lwd = 0) + # removes the census tract outline
  theme_void() +
  scale_fill_distiller(palette = "Greens",
                       breaks=c(0, .2, .4, .6, .8, 1),
                       direction = 1,
                       na.value = "transparent",
                       name="Percent Black (%)",
                       labels=percent_format(accuracy = 1L)) +
  labs(
    title = "Black population in NYC by Census Tract",
    caption = "Source: Decennial Census, 2020"
  ) + 
  geom_sf(data = boros_2263, color = "black", fill = NA, lwd = .2)


# Map Asian population by census tract
ggplot(data = nyc_race_2263, mapping = aes(fill = pct_asian))  + 
  geom_sf(color = "#ffffff", 
          lwd = 0) + # removes the census tract outline
  theme_void() +
  scale_fill_distiller(palette = "Purples",
                       breaks=c(0, .2, .4, .6, .8, 1),
                       direction = 1,
                       na.value = "transparent",
                       name="Percent Asian (%)",
                       labels=percent_format(accuracy = 1L)) +
  labs(
    title = "Asian population in NYC by Census Tract",
    caption = "Source: Decennial Census, 2020"
  ) + 
  geom_sf(data = boros_2263, color = "black", fill = NA, lwd = .2)


# Map White population by census tract
ggplot(data = nyc_race_2263, mapping = aes(fill = pct_white))  + 
  geom_sf(color = "#ffffff", 
          lwd = 0) + # removes the census tract outline
  theme_void() +
  scale_fill_distiller(palette = "Reds",
                       breaks=c(0, .2, .4, .6, .8, 1),
                       direction = 1,
                       na.value = "transparent",
                       name="Percent White (%)",
                       labels=percent_format(accuracy = 1L)) +
  labs(
    title = "White population in NYC by Census Tract",
    caption = "Source: Decennial Census, 2020"
  ) + 
  geom_sf(data = boros_2263, color = "black", fill = NA, lwd = .2)

LS0tCnRpdGxlOiAiUmFjaWFsIERlbW9ncmFwaGljcyBpbiBOZXcgWW9yayBDaXR5IgpvdXRwdXQ6CiAgaHRtbF9kb2N1bWVudDoKICAgIGRmX3ByaW50OiBwYWdlZAotLS0KCk1hcHBpbmcgcmFjZSBhY3Jvc3MgTmV3IFlvcmsgQ2l0eQoKYGBge3IgbWVzc2FnZSA9IEZBTFNFLCByZXN1bHRzPSdoaWRlJ30KbGlicmFyeSh0aWR5dmVyc2UpCmxpYnJhcnkodGlkeWNlbnN1cykKbGlicmFyeShzY2FsZXMpCmxpYnJhcnkodmlyaWRpcykKbGlicmFyeShkcGx5cikKbGlicmFyeShzZikKYGBgCgojIyMgTWV0aG9kcwoKKipQdXJwb3NlOioqIFVuZGVyc3RhbmQgY29uY2VudHJhdGlvbnMgb2YgcG9wdWxhdGlvbiBieSByYWNlIGluIE5ldyBZb3JrIENpdHkKCioqRGF0YSBzb3VyY2VzOioqIAoKKiAqMjAyMCBEZWNlbm5pYWwgQ2Vuc3VzOiogRm9yIEJyb254LCBLaW5ncywgUXVlZW5zLCBOZXcgWW9yaywgYW5kIFJpY2htb25kIGNvdW50aWVzOiBUb3RhbCBQb3B1bGF0aW9uOyBUb3RhbCBIaXNwYW5pYyBvciBMYXRpbm8sIFRvdGFsIFdoaXRlIGFsb25lLCBub3QgSGlzcGFuaWMgb3IgTGF0aW5vOyBUb3RhbCBCbGFjayBhbG9uZSwgbm90IEhpc3BhbmljIG9yIExhdGlubzsgVG90YWwgQXNpYW4gYWxvbmUsIG5vdCBIaXNwYW5pYyBvciBMYXRpbm8KCiogKk5ZQyBPcGVuIERhdGE6KiBCb3JvdWdoIGJvdW5kYXJ5IHNoYXBlZmlsZQoKKipNZXRob2RzOioqIAoKKiBIaXNwYW5pYyBwb3B1bGF0aW9uIGNhbGN1bGF0ZWQgYXMgcG9ydGlvbiBvZiB0b3RhbCBwb3B1bGF0aW9uCiogQmxhY2sgcG9wdWxhdGlvbiBjYWxjdWxhdGVkIGFzIHBvcnRpb24gb2YgdG90YWwgcG9wdWxhdGlvbgoqIEFzaWFuIHBvcHVsYXRpb24gY2FsY3VsYXRlZCBhcyBwb3J0aW9uIG9mIHRvdGFsIHBvcHVsYXRpb24KKiBXaGl0ZSBwb3B1bGF0aW9uIGNhbGN1bGF0ZWQgYXMgcG9ydGlvbiBvZiB0b3RhbCBwb3B1bGF0aW9uCiogUmVtb3ZlZCBhbGwgY2Vuc3VzIHRyYWNrcyB3aXRoIG5vIHJlc2lkZW50cwoKYGBge3IgbWVzc2FnZSA9IEZBTFNFLCByZXN1bHRzPSdoaWRlJ30KcmF3X05ZQ19yYWNlXzIwMjAgPSBnZXRfZGVjZW5uaWFsKGdlb2dyYXBoeSA9ICJ0cmFjdCIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXJpYWJsZXM9Yyh0b3RhbF9wb3AgPSAiUDFfMDAxTiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhpc3BhbmljID0gIlAyXzAwMk4iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3aGl0ZSA9ICJQMl8wMDVOIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYmxhY2sgPSAiUDJfMDA2TiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFzaWFuID0gIlAyXzAwOE4iKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RhdGU9J05ZJywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY291bnR5PWMoIkJyb254IiwgIktpbmdzIiwgIk5ldyBZb3JrIiwgIlF1ZWVucyIsICJSaWNobW9uZCIpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBnZW9tZXRyeSA9IFRSVUUsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICB5ZWFyID0gMjAyMCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb3V0cHV0ID0gIndpZGUiKQoKTllDX3JhY2VfMjAyMCA8LSByYXdfTllDX3JhY2VfMjAyMCAlPiUgCiAgbXV0YXRlKHBjdF9oaXNwYW5pYyA9IHJvdW5kKGhpc3BhbmljL3RvdGFsX3BvcCwgMyksCiAgICAgICAgIHBjdF93aGl0ZSA9IHJvdW5kKHdoaXRlL3RvdGFsX3BvcCwgMyksCiAgICAgICAgIHBjdF9ibGFjayA9IHJvdW5kKGJsYWNrL3RvdGFsX3BvcCwgMyksCiAgICAgICAgIHBjdF9hc2lhbiA9IHJvdW5kKGFzaWFuL3RvdGFsX3BvcCwgMykpICU+JSAKICBzZXBhcmF0ZShOQU1FLCBpbnRvID0gYygidHJhY3QiLCAiY291bnR5IiwgInN0YXRlIiksIHNlcCA9ICIsICIpIAoKYGBgCiMjIFJlc3VsdHMKCmBgYHtyfQpjb3VudHlfcmFjZV9zdW1tYXJ5IDwtIE5ZQ19yYWNlXzIwMjAgJT4lCiAgZ3JvdXBfYnkoY291bnR5KSAlPiUKICBzdW1tYXJpemUoCiAgICB0b3RhbF9wb3B1bGF0aW9uID0gc3VtKHRvdGFsX3BvcCwgbmEucm0gPSBUUlVFKSwKICAgIHRvdGFsX2hpc3BhbmljID0gc3VtKGhpc3BhbmljLCBuYS5ybSA9IFRSVUUpLAogICAgdG90YWxfd2hpdGUgPSBzdW0od2hpdGUsIG5hLnJtID0gVFJVRSksCiAgICB0b3RhbF9ibGFjayA9IHN1bShibGFjaywgbmEucm0gPSBUUlVFKSwKICAgIHRvdGFsX2FzaWFuID0gc3VtKGFzaWFuLCBuYS5ybSA9IFRSVUUpLAogICAgcGN0X2hpc3BhbmljID0gcGFzdGUwKHJvdW5kKCh0b3RhbF9oaXNwYW5pYyAvIHRvdGFsX3BvcHVsYXRpb24pICogMTAwLCAxKSwgIiUiKSwKICAgIHBjdF93aGl0ZSA9IHBhc3RlMChyb3VuZCgodG90YWxfd2hpdGUgLyB0b3RhbF9wb3B1bGF0aW9uKSAqIDEwMCwgMSksICIlIiksCiAgICBwY3RfYmxhY2sgPSBwYXN0ZTAocm91bmQoKHRvdGFsX2JsYWNrIC8gdG90YWxfcG9wdWxhdGlvbikgKiAxMDAsIDEpLCAiJSIpLAogICAgcGN0X2FzaWFuID0gcGFzdGUwKHJvdW5kKCh0b3RhbF9hc2lhbiAvIHRvdGFsX3BvcHVsYXRpb24pICogMTAwLCAxKSwgIiUiKSwKICAgIC5ncm91cHMgPSAiZHJvcCIKICApCgpwcmludChjb3VudHlfcmFjZV9zdW1tYXJ5KQpgYGAKClRoZSBkYXRhIHNob3dzIHRoYXQgTmV3IFlvcmsgQ2l0eSBuZWlnaGJvcmhvb2RzIGFyZSBzdGlsbCBtZWFuaW5nZnVsbHkgc2VncmVnYXRlZCBieSByYWNlLiAKCkF0IHRoZSBib3JvdWdoIGxldmVsLCB0aGUgQnJvbnggaXMgcHJlZG9taW5hbnRseSBIaXNwYW5pYyAoNTQlKSBhbmQgQmxhY2sgKDI5JSksIHdoaWxlIE1hbmhhdHRhbiBpcyBwcmVkb21pbmFudGx5IHdoaXRlICg0NyUpIGFuZCBIaXNwYW5pYyAoMjQlKS4gU3RhdGVuIElzbGFuZCBoYXMgYSBoaWdoIHBvcnRpb24gb2Ygd2hpdGUgcmVzaWRlbnRzICg1NiUpLCB3aGlsZSBRdWVlbnMgaXMgbW9yZSBkaXZlcnNlLCB3aXRoIDI4JSBIaXNwYW5pYywgMjclIEFzaWFuLCAyMyUgV2hpdGUsIGFuZCAxNiUgQmxhY2suIEZpbmFsbHksIEJyb29rbHluIGhhcyBsYXJnZSBjb25jZW50cmF0aW9ucyBvZiBXaGl0ZSByZXNpZGVudHMgKDM1JSkgYW5kIEJsYWNrIHJlc2lkZW50cyAoMjclKSwgd2l0aCBhIHNtYWxsZXIsIGJ1dCBzdGlsbCBtZWFuaW5nZnVsIHBvcnRpb24gb2YgSGlzcGFuaWMgKDE5JSkgYW5kIEFzaWFuICgxNCUpIHJlc2lkZW50cy4gCgpgYGB7ciBtZXNzYWdlID0gRkFMU0UsIHJlc3VsdHM9J2hpZGUnfQpzdF9jcnMoTllDX3JhY2VfMjAyMCkKc3RfY3JzKGJvcm9zKQpueWNfcmFjZV8yMjYzIDwtIHN0X3RyYW5zZm9ybShOWUNfcmFjZV8yMDIwLCAyMjYzKQpib3Jvc18yMjYzIDwtIHN0X3RyYW5zZm9ybShib3JvcywgMjI2MykKYGBgCgpgYGB7cn0KIyBNYXAgSGlzcGFuaWMgUG9wdWxhdGlvbiBieSBjZW51cyB0cmFjawpnZ3Bsb3QoZGF0YSA9IG55Y19yYWNlXzIyNjMsIG1hcHBpbmcgPSBhZXMoZmlsbCA9IHBjdF9oaXNwYW5pYykpICArIAogIGdlb21fc2YoY29sb3IgPSAiI2ZmZmZmZiIsIAogICAgICAgICAgbHdkID0gMCkgKyAjIHJlbW92ZXMgdGhlIGNlbnN1cyB0cmFjdCBvdXRsaW5lCiAgdGhlbWVfdm9pZCgpICsKICBzY2FsZV9maWxsX2Rpc3RpbGxlcihwYWxldHRlID0gIkJsdWVzIiwKICAgICAgICAgICAgICAgICAgICAgICBicmVha3M9YygwLCAuMiwgLjQsIC42LCAuOCwgMSksCiAgICAgICAgICAgICAgICAgICAgICAgZGlyZWN0aW9uID0gMSwKICAgICAgICAgICAgICAgICAgICAgICBuYS52YWx1ZSA9ICJ0cmFuc3BhcmVudCIsCiAgICAgICAgICAgICAgICAgICAgICAgbmFtZT0iUGVyY2VudCBIaXNwYW5pYyAoJSkiLAogICAgICAgICAgICAgICAgICAgICAgIGxhYmVscz1wZXJjZW50X2Zvcm1hdChhY2N1cmFjeSA9IDFMKSkgKwogIGxhYnMoCiAgICB0aXRsZSA9ICJIaXNwYW5pYyBvciBMYXRpbnggcG9wdWxhdGlvbiBpbiBOWUMgYnkgQ2Vuc3VzIFRyYWN0IiwKICAgIGNhcHRpb24gPSAiU291cmNlOiBEZWNlbm5pYWwgQ2Vuc3VzLCAyMDIwIgogICkgKyAKICBnZW9tX3NmKGRhdGEgPSBib3Jvc18yMjYzLCBjb2xvciA9ICJibGFjayIsIGZpbGwgPSBOQSwgbHdkID0gLjIpCgojIE1hcCBCbGFjayBwb3B1bGF0aW9uIGJ5IGNlbnN1cyB0cmFjdApnZ3Bsb3QoZGF0YSA9IG55Y19yYWNlXzIyNjMsIG1hcHBpbmcgPSBhZXMoZmlsbCA9IHBjdF9ibGFjaykpICArIAogIGdlb21fc2YoY29sb3IgPSAiI2ZmZmZmZiIsIAogICAgICAgICAgbHdkID0gMCkgKyAjIHJlbW92ZXMgdGhlIGNlbnN1cyB0cmFjdCBvdXRsaW5lCiAgdGhlbWVfdm9pZCgpICsKICBzY2FsZV9maWxsX2Rpc3RpbGxlcihwYWxldHRlID0gIkdyZWVucyIsCiAgICAgICAgICAgICAgICAgICAgICAgYnJlYWtzPWMoMCwgLjIsIC40LCAuNiwgLjgsIDEpLAogICAgICAgICAgICAgICAgICAgICAgIGRpcmVjdGlvbiA9IDEsCiAgICAgICAgICAgICAgICAgICAgICAgbmEudmFsdWUgPSAidHJhbnNwYXJlbnQiLAogICAgICAgICAgICAgICAgICAgICAgIG5hbWU9IlBlcmNlbnQgQmxhY2sgKCUpIiwKICAgICAgICAgICAgICAgICAgICAgICBsYWJlbHM9cGVyY2VudF9mb3JtYXQoYWNjdXJhY3kgPSAxTCkpICsKICBsYWJzKAogICAgdGl0bGUgPSAiQmxhY2sgcG9wdWxhdGlvbiBpbiBOWUMgYnkgQ2Vuc3VzIFRyYWN0IiwKICAgIGNhcHRpb24gPSAiU291cmNlOiBEZWNlbm5pYWwgQ2Vuc3VzLCAyMDIwIgogICkgKyAKICBnZW9tX3NmKGRhdGEgPSBib3Jvc18yMjYzLCBjb2xvciA9ICJibGFjayIsIGZpbGwgPSBOQSwgbHdkID0gLjIpCgojIE1hcCBBc2lhbiBwb3B1bGF0aW9uIGJ5IGNlbnN1cyB0cmFjdApnZ3Bsb3QoZGF0YSA9IG55Y19yYWNlXzIyNjMsIG1hcHBpbmcgPSBhZXMoZmlsbCA9IHBjdF9hc2lhbikpICArIAogIGdlb21fc2YoY29sb3IgPSAiI2ZmZmZmZiIsIAogICAgICAgICAgbHdkID0gMCkgKyAjIHJlbW92ZXMgdGhlIGNlbnN1cyB0cmFjdCBvdXRsaW5lCiAgdGhlbWVfdm9pZCgpICsKICBzY2FsZV9maWxsX2Rpc3RpbGxlcihwYWxldHRlID0gIlB1cnBsZXMiLAogICAgICAgICAgICAgICAgICAgICAgIGJyZWFrcz1jKDAsIC4yLCAuNCwgLjYsIC44LCAxKSwKICAgICAgICAgICAgICAgICAgICAgICBkaXJlY3Rpb24gPSAxLAogICAgICAgICAgICAgICAgICAgICAgIG5hLnZhbHVlID0gInRyYW5zcGFyZW50IiwKICAgICAgICAgICAgICAgICAgICAgICBuYW1lPSJQZXJjZW50IEFzaWFuICglKSIsCiAgICAgICAgICAgICAgICAgICAgICAgbGFiZWxzPXBlcmNlbnRfZm9ybWF0KGFjY3VyYWN5ID0gMUwpKSArCiAgbGFicygKICAgIHRpdGxlID0gIkFzaWFuIHBvcHVsYXRpb24gaW4gTllDIGJ5IENlbnN1cyBUcmFjdCIsCiAgICBjYXB0aW9uID0gIlNvdXJjZTogRGVjZW5uaWFsIENlbnN1cywgMjAyMCIKICApICsgCiAgZ2VvbV9zZihkYXRhID0gYm9yb3NfMjI2MywgY29sb3IgPSAiYmxhY2siLCBmaWxsID0gTkEsIGx3ZCA9IC4yKQoKIyBNYXAgV2hpdGUgcG9wdWxhdGlvbiBieSBjZW5zdXMgdHJhY3QKZ2dwbG90KGRhdGEgPSBueWNfcmFjZV8yMjYzLCBtYXBwaW5nID0gYWVzKGZpbGwgPSBwY3Rfd2hpdGUpKSAgKyAKICBnZW9tX3NmKGNvbG9yID0gIiNmZmZmZmYiLCAKICAgICAgICAgIGx3ZCA9IDApICsgIyByZW1vdmVzIHRoZSBjZW5zdXMgdHJhY3Qgb3V0bGluZQogIHRoZW1lX3ZvaWQoKSArCiAgc2NhbGVfZmlsbF9kaXN0aWxsZXIocGFsZXR0ZSA9ICJSZWRzIiwKICAgICAgICAgICAgICAgICAgICAgICBicmVha3M9YygwLCAuMiwgLjQsIC42LCAuOCwgMSksCiAgICAgICAgICAgICAgICAgICAgICAgZGlyZWN0aW9uID0gMSwKICAgICAgICAgICAgICAgICAgICAgICBuYS52YWx1ZSA9ICJ0cmFuc3BhcmVudCIsCiAgICAgICAgICAgICAgICAgICAgICAgbmFtZT0iUGVyY2VudCBXaGl0ZSAoJSkiLAogICAgICAgICAgICAgICAgICAgICAgIGxhYmVscz1wZXJjZW50X2Zvcm1hdChhY2N1cmFjeSA9IDFMKSkgKwogIGxhYnMoCiAgICB0aXRsZSA9ICJXaGl0ZSBwb3B1bGF0aW9uIGluIE5ZQyBieSBDZW5zdXMgVHJhY3QiLAogICAgY2FwdGlvbiA9ICJTb3VyY2U6IERlY2VubmlhbCBDZW5zdXMsIDIwMjAiCiAgKSArIAogIGdlb21fc2YoZGF0YSA9IGJvcm9zXzIyNjMsIGNvbG9yID0gImJsYWNrIiwgZmlsbCA9IE5BLCBsd2QgPSAuMikKYGBgIAo=