diff --git a/code/01_cohort_map.R b/code/01_cohort_map.R index a24cada..074166f 100644 --- a/code/01_cohort_map.R +++ b/code/01_cohort_map.R @@ -1,75 +1,66 @@ -## Make precinct start year cohort map ################### -## -## -## - -rmarkdown::render(input = "../code/00_read_data.Rmd") - # run 00_read_data.Rmd -# read in shootings cohort data -cure_data <- read.csv("data/output/cure_analysis_data_2020_final_cure_cohort.csv") %>% - select("precinct", "shootings_count", "shootings_per_person" , "year.x") -names(cure_data)[4]<-"year" +# read in shootings data +cure_data <- read.csv("data/output/cure_data.csv") %>% + select("precinct", "shootings_count", "shootings_per_person" , "year") cure_data$year <- as.character(cure_data$year) - # making map on categories of cohorts # too many cohorts when grouping by month & year length(unique(program_dates$date_text)) -unique(programs_20$year) +unique(programs_21$year) -names(programs_20)[c(1:6, 9:11)] - -# join to precinct shapefile +# join to precinct cohort_shp <- left_join(precinct.shp, - programs_20 %>% - select(1:6, 9:11)) %>% # keep columns of interest - mutate(year = paste0(rep(20,nrow(.)),year), # clean year text + programs_21 %>% + select(1:6, 9:11)) %>% + mutate(year = paste0(rep(20,nrow(.)),year), year = case_when(year=="20NA" ~ NA, TRUE ~ year), lab_lat = st_coordinates(st_centroid(geometry))[,1], - lab_lon = st_coordinates(st_centroid(geometry))[,2] # get precinct centriod for labeling map + lab_lon = st_coordinates(st_centroid(geometry))[,2] ) %>% #fixing year & labels for map - #filter(!grepl("2019", NA)) %>% # remove 2019 precincts but keep NA + filter(!grepl("2019", NA)) %>% # remove 2019 precincts but keep NA left_join(cure_data, by= c('precinct', 'year')) # add pre shooting numbers label_shp <- cohort_shp %>% filter(!is.na(year)) +# to remove entries for precincts with more than one Cure program +label_shp_unique <- label_shp[!(label_shp$precinct == 73 & label_shp$year == "2020"), ] +label_shp_unique <- label_shp_unique[!(label_shp_unique$precinct == 75 & label_shp_unique$year == "2015"), ] +label_shp_unique <- label_shp_unique[!(label_shp_unique$precinct == 114 & label_shp_unique$year == "2021"), ] + # Create color palete pal = colorFactor( - palette = c("#666666", "#AF6D46", "#B3B3FF","#1F3A70", "#BA9F64", "#1850B5","#660000"), # nycc_pal interpolates... + palette = c("#666666", "#AF6D46", "#B3B3FF","#1F3A70", "#BA9F64", "#1850B5","#660000", "darkgreen"), # nycc_pal interpolates... domain = label_shp$year, na.color = "#F9F9F9", reverse = T ) -# Labels when clicking on the map, use quote to modify dataframe when switching between start years, evaluate the labels in leaflet -map_labels <- quote( - paste0("When entering Cure, there have been about ", - round(label_shp$shootings_per_person*100000), - " shootings for every 100K people in ", - label_shp$neighborhood_area_serviced, " (Precinct ", - label_shp$precinct, ")", - "
", - "
","Precint: ", - label_shp$precinct, - "
","Community Organization: ", - label_shp$organization, - "
","Program Name: ", - label_shp$program_name, - "
","Council District(s): ", - label_shp$council_district, - "
","Neighborhood Area Serviced: ", - label_shp$neighborhood_area_serviced, - "
","Rounds in Program: ", - label_shp$waves, - "
","Year Entering: ", - label_shp$year, - "
","Number of Shootings: ", - label_shp$shootings_count)) - -label_shp[label_shp$year=="2019",] +# Labels when clicking on the map +map_labels <- paste0("When entering Cure, there have been about ", + round(label_shp_unique$shootings_per_person*100000), + " shootings for every 100K people in ", + label_shp_unique$neighborhood_area_serviced, " (Precinct ", + label_shp_unique$precinct, ")", + "
", + "
","Precint: ", + label_shp_unique$precinct, + "
","Community Organization: ", + label_shp_unique$organization, + "
","Program Name: ", + label_shp_unique$program_name, + "
","Council District(s): ", + label_shp_unique$council_district, + "
","Neighborhood Area Serviced: ", + label_shp_unique$neighborhood_area_serviced, + "
","Rounds in Program: ", + label_shp_unique$waves, + "
","Year Entering: ", + label_shp_unique$year, + "
","Number of Shootings: ", + label_shp_unique$shootings_count) # map m <- leaflet(options = leafletOptions(minZoom = 11, maxZoom = 13, @@ -86,88 +77,72 @@ m <- leaflet(options = leafletOptions(minZoom = 11, maxZoom = 13, fillOpacity = 1, stroke = T, color = "#CACACA") %>% - addPolygons(data = label_shp, group = "All Cure Precincts", + addPolygons(data = label_shp_unique, group = "All Cure Precincts", weight = 1, fillColor = ~pal(year), fillOpacity = 1, stroke = T, color = "#CACACA", - popup = ~lapply(eval(map_labels), HTML)) %>% - addPolygons(data = subset(label_shp, year == "2012"), + popup = ~lapply(map_labels, HTML)) %>% + addPolygons(data = label_shp_unique[label_shp_unique$year=="2012",], group = "2012", weight = 1, fillColor = ~pal(year), fillOpacity = 1, stroke = T, color = "#CACACA", - popup = ~lapply(eval(str2expression( - gsub("label_shp", - "label_shp[label_shp$year=='2012',]", - getTerms(map_labels)))), - HTML)) %>% - addPolygons(data = subset(label_shp, year == "2013"), + popup = ~lapply(map_labels, HTML)) %>% + addPolygons(data = label_shp_unique[label_shp_unique$year=="2013",], group = "2013", weight = 1, fillColor = ~pal(year), fillOpacity = 1, stroke = T, color = "#CACACA", - popup = ~lapply(eval(str2expression( - gsub("label_shp", - "label_shp[label_shp$year=='2013',]", - getTerms(map_labels)))), - HTML)) %>% - addPolygons(data = subset(label_shp, year == "2014"), + popup = ~lapply(map_labels, HTML)) %>% + addPolygons(data = label_shp_unique[label_shp_unique$year=="2014",], group = "2014", weight = 1, fillColor = ~pal(year), fillOpacity = 1, stroke = T, color = "#CACACA", - popup = ~lapply(eval(str2expression( - gsub("label_shp", - "label_shp[label_shp$year=='2014',]", - getTerms(map_labels)))), - HTML)) %>% - addPolygons(data = subset(label_shp, year == "2015"), + popup = ~lapply(map_labels, HTML)) %>% + addPolygons(data = label_shp_unique[label_shp_unique$year=="2015",], group = "2015", weight = 1, fillColor = ~pal(year), fillOpacity = 1, stroke = T, color = "#CACACA", - popup = ~lapply(eval(str2expression( - gsub("label_shp", - "label_shp[label_shp$year=='2015',]", - getTerms(map_labels)))), - HTML)) %>% - addPolygons(data = subset(label_shp, year == "2016"), + popup = ~lapply(map_labels, HTML)) %>% + addPolygons(data = label_shp_unique[label_shp_unique$year=="2016",], group = "2016", weight = 1, fillColor = ~pal(year), fillOpacity = 1, stroke = T, color = "#CACACA", - popup = ~lapply(eval(str2expression( - gsub("label_shp", - "label_shp[label_shp$year=='2016',]", - getTerms(map_labels)))), - HTML)) %>% - addPolygons(data = subset(label_shp, year == "2019"), + popup = ~lapply(map_labels, HTML)) %>% + addPolygons(data = label_shp_unique[label_shp_unique$year=="2019",], group = "2019", weight = 1, fillColor = ~pal(year), fillOpacity = 1, stroke = T, color = "#CACACA", - popup = ~lapply(eval(str2expression( - gsub("label_shp", - "label_shp[label_shp$year=='2019',]", - getTerms(map_labels)))), - HTML)) %>% - addLabelOnlyMarkers(lat = label_shp$lab_lon, - lng = label_shp$lab_lat, - label = label_shp$precinct, + popup = ~lapply(map_labels, HTML)) %>% + addPolygons(data = label_shp_unique[label_shp_unique$year=="2021",], + group = "2021", + weight = 1, + fillColor = ~pal(year), + fillOpacity = 1, + stroke = T, + color = "#CACACA", + popup = ~lapply(map_labels, HTML)) %>% + addLabelOnlyMarkers(lat = label_shp_unique$lab_lon, + lng = label_shp_unique$lab_lat, + label = label_shp_unique$precinct, labelOptions = labelOptions(permanent = TRUE, noHide = TRUE, textOnly = TRUE, @@ -185,6 +160,8 @@ m <- leaflet(options = leafletOptions(minZoom = 11, maxZoom = 13, position = "topleft", baseGroups = c("All Cure Precincts", "2012", "2013","2014", - "2015", "2016", "2019")) + "2015", "2016", "2019", "2021")) + +m saveWidget(m, file = "visuals/cohort_map.html") diff --git a/code/02_precinct-shootings-change-dataset_2011_2020.ipynb b/code/02_precinct-shootings-change-dataset_2011_2020.ipynb index 4a2c3d0..5533342 100644 --- a/code/02_precinct-shootings-change-dataset_2011_2020.ipynb +++ b/code/02_precinct-shootings-change-dataset_2011_2020.ipynb @@ -2,7 +2,7 @@ "cells": [ { "cell_type": "code", - "execution_count": 1, + "execution_count": 4, "id": "73671aa5", "metadata": {}, "outputs": [], @@ -13,7 +13,7 @@ }, { "cell_type": "code", - "execution_count": 2, + "execution_count": 6, "id": "501fa32b", "metadata": {}, "outputs": [], @@ -29,7 +29,7 @@ }, { "cell_type": "code", - "execution_count": 3, + "execution_count": 7, "id": "4a231db5", "metadata": { "scrolled": true @@ -39,17 +39,17 @@ "name": "stderr", "output_type": "stream", "text": [ - "/var/folders/0x/wbh6lcrn3t7046vw2zxtbrhxrc0v0g/T/ipykernel_41186/80947141.py:24: SettingWithCopyWarning: \n", + "/var/folders/0x/wbh6lcrn3t7046vw2zxtbrhxrc0v0g/T/ipykernel_89827/735278083.py:24: SettingWithCopyWarning: \n", "A value is trying to be set on a copy of a slice from a DataFrame\n", "\n", "See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy\n", " precinct_df['change_from_start_year'][ind] = ''\n", - "/var/folders/0x/wbh6lcrn3t7046vw2zxtbrhxrc0v0g/T/ipykernel_41186/80947141.py:20: SettingWithCopyWarning: \n", + "/var/folders/0x/wbh6lcrn3t7046vw2zxtbrhxrc0v0g/T/ipykernel_89827/735278083.py:20: SettingWithCopyWarning: \n", "A value is trying to be set on a copy of a slice from a DataFrame\n", "\n", "See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy\n", " precinct_df['change_from_start_year'][ind] = round(((end_count - start_count) / start_count) * 100, 2)\n", - "/var/folders/0x/wbh6lcrn3t7046vw2zxtbrhxrc0v0g/T/ipykernel_41186/80947141.py:26: FutureWarning: The frame.append method is deprecated and will be removed from pandas in a future version. Use pandas.concat instead.\n", + "/var/folders/0x/wbh6lcrn3t7046vw2zxtbrhxrc0v0g/T/ipykernel_89827/735278083.py:26: FutureWarning: The frame.append method is deprecated and will be removed from pandas in a future version. Use pandas.concat instead.\n", " shootings_change_df = shootings_change_df.append(precinct_df, ignore_index=True) # combine all precinct-specific DFs into one\n" ] } @@ -84,6 +84,258 @@ " start_year_list.append(start_year) # add each precinct's start year to this list (will be used later)" ] }, + { + "cell_type": "code", + "execution_count": 8, + "id": "46109999", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
precinctyeartimecuretime_after_intp0010001shootings_countshootings_per_personarrests_countarrests_per_popchange_from_start_year
023201160073106410.00056162410.085369
123201270073106320.00043856960.077914
223201380073106120.00016457000.077969
323201490073106160.00021955020.075261
4232015100073106230.00031551410.070323
....................................
20512020161113113008250.00022148510.042926-40.48
20612020171214113008270.00023947420.041962-35.71
20712020181315113008200.00017745870.040590-52.38
20812020191416113008120.00010637040.032776-71.43
20912020201517113008190.0001681020.000903-54.76
\n", + "

210 rows × 11 columns

\n", + "
" + ], + "text/plain": [ + " precinct year time cure time_after_int p0010001 shootings_count \\\n", + "0 23 2011 6 0 0 73106 41 \n", + "1 23 2012 7 0 0 73106 32 \n", + "2 23 2013 8 0 0 73106 12 \n", + "3 23 2014 9 0 0 73106 16 \n", + "4 23 2015 10 0 0 73106 23 \n", + ".. ... ... ... ... ... ... ... \n", + "205 120 2016 11 1 3 113008 25 \n", + "206 120 2017 12 1 4 113008 27 \n", + "207 120 2018 13 1 5 113008 20 \n", + "208 120 2019 14 1 6 113008 12 \n", + "209 120 2020 15 1 7 113008 19 \n", + "\n", + " shootings_per_person arrests_count arrests_per_pop \\\n", + "0 0.000561 6241 0.085369 \n", + "1 0.000438 5696 0.077914 \n", + "2 0.000164 5700 0.077969 \n", + "3 0.000219 5502 0.075261 \n", + "4 0.000315 5141 0.070323 \n", + ".. ... ... ... \n", + "205 0.000221 4851 0.042926 \n", + "206 0.000239 4742 0.041962 \n", + "207 0.000177 4587 0.040590 \n", + "208 0.000106 3704 0.032776 \n", + "209 0.000168 102 0.000903 \n", + "\n", + " change_from_start_year \n", + "0 \n", + "1 \n", + "2 \n", + "3 \n", + "4 \n", + ".. ... \n", + "205 -40.48 \n", + "206 -35.71 \n", + "207 -52.38 \n", + "208 -71.43 \n", + "209 -54.76 \n", + "\n", + "[210 rows x 11 columns]" + ] + }, + "execution_count": 8, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "shootings_change_df" + ] + }, { "cell_type": "code", "execution_count": 4, @@ -536,7 +788,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.9.13" + "version": "3.11.1" } }, "nbformat": 4, diff --git a/code/04_map-shooting-averages_by-precinct_2006_2012.R b/code/04_map-shooting-averages_by-precinct_2006_2012.R index 8b14209..3b1812f 100644 --- a/code/04_map-shooting-averages_by-precinct_2006_2012.R +++ b/code/04_map-shooting-averages_by-precinct_2006_2012.R @@ -3,9 +3,8 @@ shootings_06_12 <- read.csv('data/output/NYC-precinct-shootings_mean_2006_2012.c precinct.shp <- st_read("data/input/Police\ Precincts/geo_export_ece0487d-79ca-4c55-898e-8333b6d2b0bc.shp") precinct.shp <- st_transform(precinct.shp,'+proj=longlat +datum=WGS84') - # just precincts in cure -program_dates <- read.csv("data/output/cure_analysis_data_2020_final.csv") +program_dates <- read.csv('data/output/programMerge.csv') precincts_in_cure <- unique(program_dates$precinct) # joining shootings per person data with precinct shape file @@ -17,15 +16,6 @@ shootings_06_12.shp <- shootings_06_12.shp %>% # converting NaN to 0 shootings_06_12.shp[is.na(shootings_06_12.shp)] <- 0 -# fitler version -filter_light <- shootings_06_12.shp %>% - filter(precinct %in% precincts_in_cure) %>% - filter(shootings_per_100K <= 51.3) - -filter_dark <- shootings_06_12.shp %>% - filter(precinct %in% precincts_in_cure) %>% - filter(shootings_per_100K > 51.3) - # check column distribution plot(density(shootings_06_12.shp$shootings_per_100K, na.rm = T)) hist(shootings_06_12.shp$shootings_per_100K, breaks = 20) @@ -36,15 +26,23 @@ int_prct <- classIntervals(shootings_06_12.shp$shootings_per_100K, #blue_pal <- c('#e7eefb', '#cdd4f5', '#98a3ea', '#5675dd', '#1d5fd6') -# creating color palete -palPct = colorBin( - palette = nycc_pal("blue")(7), + +# use the custom palette function in colorBin +palPct <- colorBin( + palette = "nycc_blue", bins = int_prct$brks, domain = shootings_06_12.shp$shootings_per_100K, na.color = "#E6E6E6", reverse = FALSE ) +# finding the centroids of all of the precincts for labeling +shootings_06_12.shp <- shootings_06_12.shp %>% + mutate(lab_lat = st_coordinates(st_centroid(geometry, + of_largest_polygon = T))[,1], + lab_lon = st_coordinates(st_centroid(geometry, + of_largest_polygon = T))[,2]) + # labels when clicking on the map map_labels <- paste0("Precinct: ", shootings_06_12.shp$precinct, @@ -53,13 +51,14 @@ map_labels <- paste0("Precinct: ", # cure precinct control cure_pcts<- HTML('
Cure Precincts
') -# finding the centroids of all of the precincts for labeling -shootings_06_12.shp <- shootings_06_12.shp %>% - mutate(lab_lat = st_coordinates(st_centroid(geometry, - of_largest_polygon = T))[,1], - lab_lon = st_coordinates(st_centroid(geometry, - of_largest_polygon = T))[,2]) +# fitler version +filter_light <- shootings_06_12.shp %>% + filter(precinct %in% precincts_in_cure) %>% + filter(shootings_per_100K <= 51.3) +filter_dark <- shootings_06_12.shp %>% + filter(precinct %in% precincts_in_cure) %>% + filter(shootings_per_100K > 51.3) # creating the choropleth m <- leaflet(options = leafletOptions(minZoom = 11, maxZoom = 13, @@ -77,7 +76,7 @@ m <- leaflet(options = leafletOptions(minZoom = 11, maxZoom = 13, fillOpacity = 1, popup = ~map_labels, smoothFactor = 0) %>% - addPolylines(data = boro, weight = 0.7, + addPolylines(data = boro, weight = 0.7, # read in boro in 00_read_data.Rmd stroke = TRUE, color = "#666666") %>% addPolylines(data = shootings_06_12.shp %>% @@ -104,9 +103,9 @@ m <- leaflet(options = leafletOptions(minZoom = 11, maxZoom = 13, textOnly = TRUE, textsize = 4, direction = "auto", - style = list(color = "#23417D", - "font-family" = google_font('Open Sans'), - "font-weight" = "normal"))) %>% + style = list(color = "#23417D", + "font-family" = google_font('Open Sans'), + "font-weight" = "normal"))) %>% addLabelOnlyMarkers(data = filter_dark, lat = filter_dark$lab_lon, # adding precinct labels lng = filter_dark$lab_lat, @@ -120,4 +119,9 @@ m <- leaflet(options = leafletOptions(minZoom = 11, maxZoom = 13, "font-family" = google_font('Open Sans'), "font-weight" = "normal"))) -#saveWidget(m, file = "visuals/avg_shootings_map.html") + + +m + +saveWidget(m, file = "visuals/avg_shootings_map.html") + diff --git a/code/04_precinct-shootings-change-table.R b/code/04_precinct-shootings-change-table.R new file mode 100644 index 0000000..6d7f44f --- /dev/null +++ b/code/04_precinct-shootings-change-table.R @@ -0,0 +1,93 @@ +# run 00_read_data.Rmd +# read in cleaned shootings data ----------- +cure_data <- read.csv("data/output/shootings-change-from-start-year_by-precinct.csv") %>% + replace(is.na(.), "") %>% # remove NAs + mutate(across(2:9, as.numeric)) # make all numeric + +# clean column names +names(cure_data)[2:11] <- seq(2011, 2020, 1) + +# check values' distribution for color binning-classification +# c <- unlist(list(cure_data$`2011`,cure_data$`2012`, cure_data$`2013`, cure_data$`2014`, cure_data$`2015`, cure_data$`2016`, cure_data$`2017`, cure_data$`2018`, cure_data$`2019`, cure_data$`2020`)) +# hist(c, breaks = 30) +# hist(c, breaks = 7) +###### gt table --------- + +gt_table <- cure_data %>% + gt(rowname_col = "precinct", + groupname_col = "groupname") %>% + + # gtExtras::gt_plt_sparkline(sparkline) %>% + tab_header(title = "% Change in Shootings from Year Before Precincts entered Cure Violence Program", + subtitle = "In Order by Year of Entry") %>% + tab_stubhead(label = "Precinct") %>% + gt_theme_nytimes() %>% + sub_missing(missing_text = "") %>% + data_color(columns = starts_with("20"), + rows = everything(), + method = "numeric", + colors = + scales::col_bin( + bins = c(-100,-50,-10,-1,0,1,20,100,150,350), + na.color = "transparent", + palette = nycc_pal("diverging", reverse = T)(7)), + contrast_algo = "wcag") %>% + fmt_percent(columns = starts_with("20"), + decimals = 0, scale_values = F) %>% + tab_style(style = list(cell_text(weight = "bold"), + cell_borders(sides = c("left", "right"), + style = "double", + color = "#e6e6e6", + weight = px(2))), + locations = cells_body(rows = c(1:2), + columns = "2012")) %>% + tab_style(style = list(cell_text(weight = "bold"), + cell_borders(sides = c("left", "right"), + style = "double", + color = "#e6e6e6", + weight = px(2)) ), + locations = cells_body(rows = c(3:4), + columns = "2013")) %>% + tab_style(style = list(cell_text(weight = "bold"), + cell_borders(sides = c("left", "right"), + style = "double", + color = "#e6e6e6", + weight = px(2))), + locations = cells_body(rows = c(5), + columns = "2014")) %>% + tab_style(style = list(cell_text(weight = "bold"), + cell_borders(sides = c("left", "right"), + style = "double", + color = "#e6e6e6", + weight = px(2)) ), + locations = cells_body(rows = c(6:11), + columns = "2015")) %>% + tab_style(style = list(cell_text(weight = "bold"), + cell_borders(sides = c("left", "right"), + style = "double", + color = "#e6e6e6", + weight = px(2)) ), + locations = cells_body(rows = c(12:17), + columns = "2016")) %>% + tab_style(style = list(cell_text(weight = "bold"), + cell_borders(sides = c("left", "right"), + style = "double", + color = "#e6e6e6", + weight = px(2)) ), + locations = cells_body(rows = c(18:21), + columns = "2019")) %>% + tab_style(style = cell_borders(sides = "bottom", + style = "double", + color = "#CACACA", + weight = px(2)), + locations = cells_body(columns = "precinct", + rows = c(2,4,5,11,17)) ) %>% + tab_style(style = cell_text(color = "#222222", + size = px(13), + font = google_font("Open Sans")), + locations = cells_column_labels()) %>% + opt_table_font(font = list(google_font(name = "Open Sans") )) %>% + rm_header() + + +gtsave(gt_table, "visuals/precinct-shootings-change-table.html")