This notebook performs preliminary descriptive analysis and mapping of ICE/CBP apprehensions in Washington state, based on a collection of I-213 forms obtained by the University of Washington Center for Human Rights (UWCHR) via a Freedom of Information Act (FOIA) lawsuit against the US Department of Homeland Security.
Data used in this analysis were scraped from PDF forms and cleaned in a separate private repository. I-213 narratives and other potentially sensitive fields have been excluded from analysis. Data scraping and cleaning code available for review upon request.
knitr::opts_chunk$set(echo = TRUE)
pacman::p_load(tidyverse, lubridate, here, skimr, yaml, ggplot2, ggalt, ggsflabel,
sf, rnaturalearth, rnaturalearthdata, maps, tools, RColorBrewer
)
inputfile <- here::here('map', 'input', 'uw-chr-i213-public.csv.gz')
i213 <- read_delim(inputfile, delim = "|",
col_types = cols(
.default = col_character(),
source = col_factor(),
sex = col_factor(),
year = col_double(),
month = col_double(),
day = col_double(),
hour = col_double(),
minute = col_double(),
age = col_double(),
accompanied_juvenile_flag = col_double(),
unaccompanied_juvenile_flag = col_double(),
custody_redetermination_flag = col_double())
)
i213 <- i213 %>%
filter(source == 'ice',
state == 'WA',
year >= '2019')
priority_counties <- read_yaml('../../shared/hand/priority_counties.yaml')
priority_counties <- gsub(" County", "", priority_counties)
priority_counties <- tolower(priority_counties)
priority_plus <- append(priority_counties, 'whatcom')
i213$date <- as.Date(i213$date)
min_date <- min(i213$date, na.rm = TRUE)
max_date <- max(i213$date, na.rm = TRUE)
at_near
locationMost (but not all) I-213 forms include a field labeled “At/Near” that describes the location of the apprehension, usually as a “city, state” pair, but occasionally using other values such as the name of a jail or prison, or agency code for points of entry, such as “SEA” (SeaTac Airport) or “PHY” (Pacific Highway in Blaine, WA). Where “At/Near” values are ambiguous or missing, UWCHR has confirmed apprehension location based on I-213 narratives. After cleaning, locations are assigned latitude/longitude values using Google Maps API.
world <- ne_countries(scale = "medium", returnclass = "sf")
states <- st_as_sf(map("state", crs = 4326, plot = FALSE, fill = TRUE))
states <- cbind(states, st_coordinates(st_point_on_surface(states)))
states$ID <- toTitleCase(as.character(states$ID))
wa <- states %>%
filter(ID == 'Washington')
counties <- st_as_sf(map("county", plot = FALSE, fill = TRUE))
counties <- counties %>%
separate(col = 'ID', into = c("state", "county"), sep = ",", remove = FALSE) %>%
filter(state == 'washington')
counties$area <- as.numeric(st_area(counties))
sites <- i213 %>% select(lon, lat) %>%
na.omit()
sites <- st_as_sf(sites, coords = c("lon", "lat"),
crs = 4326, agr = "constant")
wa_coords <- coord_sf(xlim = c(-125, -116.5), ylim = c(45, 49.5), expand = FALSE, crs = 4326)
st_crs(wa) <- 4326
st_crs(wa$geom) <- 4326
st_crs(sites) <- 4326
st_crs(sites$geometry) <- 4326
ggplot(data = wa) +
geom_sf() +
geom_sf(data = wa, fill = NA) +
geom_sf(data = counties, fill = NA) +
geom_sf(data = sites, size = 2, shape = 23, fill = "red") +
wa_coords +
ggtitle('I-213 forms by "at_near" latitude/longitude')
Note distribution of arrests throughout the state, with larger clusters along the northern border in Whatcom County and in SeaTac, locaiton of both the Seattle-Tacoma International Airport and SeaTac Federal Detention Center.
data_at_near <- i213 %>%
filter(year >= '2019') %>%
group_by(at_near, lon, lat) %>%
summarise(n = n()) %>%
na.omit()
data_at_near <- st_as_sf(data_at_near, coords = c("lon", "lat"),
crs = 4326, agr = "constant")
data_at_near$rank <- rank(data_at_near$n)
p1 <- ggplot(data = wa) +
geom_sf() +
geom_sf(data = wa, fill = NA) +
geom_sf(data = counties, fill = NA) +
geom_sf(data = data_at_near, aes(size=n), shape = 21, fill = "red", alpha=.5) +
wa_coords +
labs(x = NULL, y = NULL,
title = "Count of I-213 apprehensions by `at_near` location",
subtitle = paste(min_date, max_date, sep = ' to '),
caption = "UW Center for Human Rights")
p1
ggsave('wa-i213-count.png',
plot = p1,
device = 'png',
path = '../output',
scale = 1,
dpi = 300)
p2 <- ggplot(data = wa) +
geom_sf() +
geom_sf(data = wa, fill = NA) +
geom_sf(data = counties, fill = NA) +
geom_sf(data = data_at_near, aes(size=n), shape = 21, fill = "red", alpha=.5) +
ggsflabel::geom_sf_label_repel(data = subset(data_at_near, rank > (nrow(data_at_near) - 5)),
aes(label = paste(at_near, n, sep=': '),
background = NA),
force = 50,
nudge_x = -.33,
nudge_y = .33) +
wa_coords +
labs(x = NULL, y = NULL,
title = "Count of I-213 apprehensions by `at_near` location",
subtitle = paste(min_date, max_date, sep = ' to '),
caption = "UW Center for Human Rights")
p2
ggsave('wa-i213-count-labeled.png',
plot = p2,
device = 'png',
path = '../output',
scale = 1,
dpi = 300)
Here we sum total arrests by county, and also generate a simple diagram of priority counties selected for UWCHR’s “Immigrant Rights Observatory” project.
data <- i213 %>%
group_by(county, state) %>%
summarise(n = n()) %>%
na.omit()
data$state <- data$state %>%
str_replace_all(c("WA" = "washington", "OR" = "oregon", 'ID' = 'idaho', 'AK' = 'alaska'))
data$county <- data$county %>%
str_replace_all(c(" County" = "")) %>%
tolower()
data$ID <- paste(data$state, data$county, sep=',')
counties <- left_join(counties, data, by=c("ID", "state", 'county'))
study_counties <- counties %>%
filter(county %in% priority_counties)
m1 <- ggplot(data = wa) +
geom_sf() +
geom_sf(data = wa, fill = NA) +
geom_sf(data = counties, aes(fill = n)) +
ggsflabel::geom_sf_label_repel(data = study_counties, aes(label = str_to_title(county)),
nudge_x = -.33,
nudge_y = .33,
force = 75) +
scale_fill_viridis_c(trans = "sqrt", alpha = .4, na.value = gray(.9)) +
wa_coords +
labs(x = NULL, y = NULL,
title = "Total I-213 apprehensions by county",
subtitle = paste(min_date, max_date, sep = ' to '),
caption = "UW Center for Human Rights")
m1
ggsave('wa-i213-county-total.png',
plot = m1,
device = 'png',
path = '../output',
scale = 1,
dpi = 300)
m2 <- ggplot(data = wa) +
geom_sf() +
geom_sf(data = wa, fill = NA) +
geom_sf(data = counties, fill = NA) +
geom_sf(data = study_counties, aes(fill = 'priority')) +
geom_sf_label_repel(data = study_counties, aes(label = str_to_title(county), background = NA), force = 0) +
wa_coords +
labs(x = NULL, y = NULL, fill = NULL,
title = "Immigrant Rights Observatory priority counties",
caption = "UW Center for Human Rights") +
annotate("text", x = 4, y = 25, label = "Some text") +
theme(legend.position = "none") + scale_fill_manual(values=c("#b7a57a"))
m2
ggsave('wa-priority-counties.png',
plot = m2,
device = 'png',
path = '../output',
scale = 1,
dpi = 300)
Here we calculate and map rate of I-213 apprehensions per capita, using ACS 5 year 2014-2018 population estimates.
wa_pop <- read.delim(here::here('map', 'input', 'wa-pop.csv'), sep=',')
wa_total_pop <- wa_pop %>%
filter(name == "washington")
wa_total_pop <- wa_total_pop$estimate
wa_pop <- wa_pop %>%
filter(name != "washington")
wa_pop$name <- gsub(" county", "", wa_pop$name)
wa_pop$name <- str_trim(wa_pop$name)
wa_pop <- wa_pop %>%
separate(., col=name, sep=',',
remove = FALSE,
into=c('county', 'state'))
wa_pop$state <- str_trim(wa_pop$state)
wa_pop$county <- str_trim(wa_pop$county)
wa_pop <- wa_pop %>%
mutate(priority = county %in% priority_counties)
wa_pop <- wa_pop %>%
mutate(priority_plus = county %in% priority_plus)
wa_pop_prior <- wa_pop %>%
filter(priority == TRUE)
wa_pop_prior_plus <- wa_pop %>%
filter(priority_plus == TRUE)
wa_pop_prior <- sum(wa_pop_prior$estimate)
wa_pop_prior_plus <- sum(wa_pop_prior_plus$estimate)
prop_pop_prior <- wa_pop_prior / wa_total_pop
wa_pop_prior_plus <- wa_pop_prior_plus / wa_total_pop
# merge and calcuiate n forms per capita
data <- merge(counties, wa_pop, by=c('county', 'state'))
data$i_213_per_capita <- data$n / data$estimate * 100000
# Checking # of forms in priority counties
forms_wa <- data %>%
filter(state == 'washington')
forms_prior <- data %>%
filter(priority == TRUE)
forms_prior_plus <- data %>%
filter(priority_plus == TRUE)
wa_forms_prior <- sum(forms_prior$n) / sum(forms_wa$n)
wa_forms_prior_plus <- sum(forms_prior_plus$n) / sum(forms_wa$n)
total_forms_prior <- sum(forms_prior$n) / sum(data$n)
m1 <- ggplot(data = wa) +
geom_sf() +
geom_sf(data = wa, fill = NA) +
geom_sf(data = data, aes(fill = i_213_per_capita)) +
wa_coords +
ggsflabel::geom_sf_label_repel(data = study_counties, aes(label = str_to_title(county), background = NA), force = 100) +
labs(x = NULL, y = NULL,
title = "Per capita I-213 apprehensions by county",
subtitle = paste(min_date, max_date, sep = ' to '),
caption = "UW Center for Human Rights\n2014-2018 population estimate via ACS") +
guides(fill=guide_colorbar(title="Arrests per\n100,000")) +
scale_fill_viridis_c(trans = "sqrt", alpha = .4, na.value = gray(.9))
m1
ggsave('wa-i213-county-per-capita.png',
plot = m1,
device = 'png',
path = '../output',
scale = 1,
dpi = 300)
Table of apprehensions per capita:
to_print <- data %>%
select(c('county', 'n', 'estimate', 'i_213_per_capita')) %>%
mutate(county = str_to_title(county))
st_geometry(to_print) <- NULL
total_arrests <- sum(to_print$n, na.rm=TRUE)
wa_per_capita <- total_arrests / wa_total_pop * 100000
to_print <- to_print %>%
add_row(county = 'Washington state total',
estimate = wa_total_pop,
n = total_arrests,
i_213_per_capita = wa_per_capita)
to_print <- to_print %>%
arrange(desc(i_213_per_capita))
col_names <- c('County', 'Total apprehensions', 'Population','Apprehensions per capita')
caption <- paste("WA State I-213 apprehensions per capita\n", min_date, " to ", max_date, sep='')
caption_html <- paste("<b>WA State I-213 apprehensions per capita</b><br><i>", min_date, " to ", max_date, sep='')
write(knitr::kable(to_print, caption = caption_html, col.names = col_names, digits=4, 'html'), '../output/i213-per-capita.html')
print(knitr::kable(to_print, caption = caption, col.names = col_names, digits=4))
##
##
## Table: WA State I-213 apprehensions per capita
## 2019-01-01 to 2020-04-02
##
## |County | Total apprehensions| Population| Apprehensions per capita|
## |:----------------------|-------------------:|----------:|------------------------:|
## |Adams | 63| 19452| 323.8742|
## |Whatcom | 540| 216812| 249.0637|
## |Okanogan | 82| 41638| 196.9355|
## |Grant | 137| 94860| 144.4234|
## |Franklin | 128| 90660| 141.1869|
## |Grays Harbor | 53| 71967| 73.6449|
## |Mason | 41| 62627| 65.4670|
## |Pacific | 9| 21281| 42.2912|
## |Skagit | 50| 123907| 40.3528|
## |Ferry | 3| 7576| 39.5987|
## |Klickitat | 8| 21396| 37.3902|
## |Benton | 72| 194168| 37.0813|
## |Washington state total | 2543| 7294336| 34.8627|
## |King | 708| 2163257| 32.7284|
## |Chelan | 22| 75757| 29.0402|
## |Spokane | 132| 497875| 26.5127|
## |Lewis | 20| 76947| 25.9919|
## |Yakima | 63| 249325| 25.2682|
## |Clark | 85| 465384| 18.2645|
## |Walla Walla | 10| 60236| 16.6014|
## |Clallam | 12| 74487| 16.1102|
## |Snohomish | 122| 786620| 15.5094|
## |Pierce | 117| 859840| 13.6072|
## |Cowlitz | 14| 105112| 13.3191|
## |Whitman | 6| 48593| 12.3475|
## |Skamania | 1| 11620| 8.6059|
## |Kitsap | 20| 262475| 7.6198|
## |Stevens | 3| 44214| 6.7852|
## |Kittitas | 3| 44825| 6.6927|
## |Island | 4| 81636| 4.8998|
## |Douglas | 2| 41371| 4.8343|
## |Thurston | 13| 274684| 4.7327|
## |Asotin | NA| 22337| NA|
## |Columbia | NA| 4001| NA|
## |Garfield | NA| 2224| NA|
## |Jefferson | NA| 30856| NA|
## |Lincoln | NA| 10435| NA|
## |Pend Oreille | NA| 13219| NA|
## |San Juan | NA| 16473| NA|
## |Wahkiakum | NA| 4189| NA|