library(stringr)
# Get the current page number from the file name
current_page <- as.numeric(str_extract(knitr::current_input(), "\\d+"))
# Set the total number of pages
total_pages <- 9
# Generate the URLs for the previous and next pages
previous_page <- ifelse(current_page > 1, paste0("visual_", current_page - 1, "-darfur_violence-code_included.html"), NA)
next_page <- ifelse(current_page < total_pages, paste0("visual_", current_page + 1, "-darfur_violence-code_included.html"), NA)
# Note: All code, insights shared, and methodological notes in this document and other documents in this portfolio ARE NOT open source and MUST be cited.
# For this page, I create 3 sets of paired faceted choropleth maps of Darfur, Sudan based on the average number of troops (derived from the Geo-PKO dataset) stationed at UN bases from the UNAMID peacekeeping mission in second level administrative regions. These administrative units are colored in the maps based on the average number of UN troops stationed in the regions during a given year. The location of recently closed down UN bases (also based on the Geo-PKO dataset) are plotted with blue dots. The maps will also show the location of attacks on civilians and fatality numbers from these attacks (plotted on the maps with transparent red bubbles) as recorded in the ACLED dataset. I will create buffers (having radii of 50 mi) around bases that were abandoned by the UN, and calculate inside these buffers the number of attacks on civilians and fatalities the year before the bases were closed vs. the year they were closed.
# The UN bases (also known as "team sites") withdrawn from West Darfur included the Forobaranga and Habila bases in 2017 Masteri and Mournei in 2018, and the El Geneina base in 2019. See the following sources I relied on for UN base closure dates:
# https://oios.un.org/file/8866/download?token=F6tc9ZI5 (pg. 31) - documents sites closed from 2017-2019 (I consider "team sites" and "section headquarters" as UN bases since troops are normally stationed at these types of compounds)
# https://www.ecoi.net/en/file/local/2052225/S_2021_470_E.pdf (pg. 24) - documents sites closed in 2021
# Note: No UN bases were closed in 2020, but were closed in 2021.
# I therefore create 3 sets of paired faceted maps: one comparing attacks on civilians and fatalities within 50 mi from the Forobaranga and Habila bases in 2016 vs. 2017, one that does the same within 50 mi of the Masteri and Mournei bases in 2017 vs. 2018, and another that does the same within 50 mi of the El Geneina base in 2018 vs. 2019. However, no bases in West Darfur were withdrawn after 2019, so I do not create faceted maps comparing West Darfur violence in 2019 vs. 2020 or in 2020 vs. 2021. Nevertheless, I later calculate numbers of attacks on civilians and fatalities each year from 2016-2021 inside the buffers surrounding the UN bases withdrawn in 2017, 2018, and 2019 for a quantitative analysis of violence trends.
# Below, I start by reading in my Darfur map shapefile comprising second level administrative units, the ACLED dataset on violence against civilians comprising locations of attacks on civilians and fatalities resulting from these attacks, and the Geo-PKO dataset's variables on active UN base locations and troop numbers reported at each base on multiple occasions each year. For this last dataset, I create a variable showing the average number of troops stationed at each active UN base during a given year.
# Note: The sources listed above which provide accurate dates of UN base closures in Darfur enabled me to correctly edit some of the bases in the Geo-PKO dataset which incorrectly showed as being active in Darfur after they had in reality already been closed.
# After reading in the datasets, I convert them to "simple feature" (sf) spatial objects that will later be used to plot faceted tmap choropleth maps showing yearly differences in UN troop numbers from active UN bases across second level administrative units, and locations of attacks on civilians and fatalities. However, before mapping occurs, I must spatially join part of the ACLED violence against civilians dataset per year to the Darfur map, and the Geo-PKO dataset locations of active UN bases and average troop numbers per year to the Darfur map.
# I will be using a Projected Coordinate Reference System (PCRS) when creating maps and when making buffer-based calculations within a 50 mi radius of closed UN base locations on these maps. The choice of whether to use a PCRS or a Geographic Coordinate Reference System (GCRS) is based on the following criteria:
# PCRSs are often better to use than Geographic Coordinate Reference Systems (GCRSs) when mapping or computing calculations from maps at the country-level, state/province/regional level, or city level because PCRSs are localized to a particular geographic region to minimize measurement distortions. A PCRS typically will only work well for measurements of distances or areas for the specific geographic location it was designed for rather than the entire globe. PCRSs are based on a plane, which results from a spheroid projected onto a 2D surface, and utilize linear units (feet, meters, etc.) for expressing coordinates.
# In contrast, GCRSs span the entire globe (e.g., longitude and latitude) and are based on a spheroid. They use angular units (degrees) for expressing coordinates. If you need to represent locations across the entire globe (like for a world map), then a Geographic CRS would be more appropriate because doing so with a PCRS may create distorted maps and measurements at this level.
# Since I focus on the Darfur region within Sudan, it is better to use a PCRS. For making my maps and my buffer-based calculations on these maps, I will use the PCRS - EPSG:20135 - a version of the Universal Transverse Mercator (UTM) system. However, I will first use a GCRS when converting objects to sf spatial objects - specifically EPSG:4326, also known as the World Geodetic System 1984 (WGS84). I use this GCRS since the Darfur polygon map shapefile I will be using is based on this, and since it is generally good practice to use a GCRS before transforming spatial objects to a localized PCRS.
# The reason this is often considered good practice is because geographic coordinates (latitude and longitude) are the most common form of spatial reference we usually encounter in objects before they are converted to sf format. Starting with these geographic coordinates, GCRS ensures you are working with the most raw, untransformed version of your data. This can help prevent the introduction of errors or distortions that might occur during the projection process.
# Why use EPSG:20135 (also known as the Adindan/Universal Transverse Mercator (UTM) zone 35N system)? This PCRS covers parts of Northeast Africa - including areas of Sudan between 24°E and 30°E. Darfur, Sudan is located at approximately 13°N, 25°E, which thus places most of it in UTM Zone 35N. Since EPSG:20135 is measured in meters, I will convert each measurement into miles when creating the buffers.
library(rgdal)
library(tidyverse)
library(tmap)
library(sp)
library(sf)
setwd("C:/Users/rsb84/Desktop/RB/COLUMBIA/QMSS/COURSES/Spring_2021/Data Visualization/End_project")
darfur_internal<-raster::shapefile("C:/Users/rsb84/Desktop/RB/COLUMBIA/QMSS/COURSES/Spring_2021/Data Visualization/End_project/darfur_internal.shp")
# Convert to a simple feature spatial object
darfur_internal_sf <- sf::st_as_sf(darfur_internal)
original_crs <- st_crs(darfur_internal) #Original CRS is EPSG:4326, i.e., the World Geodetic System 1984 (WGS84), a geographic CRS
CRS.new <- st_crs("EPSG:20135") #This is a projected CRS well-suited for Darfur
darfur_internal_sf <- st_transform(darfur_internal_sf, crs = CRS.new) # Transform the CRS to EPSG:20135
ACLED_data <- readxl::read_excel("ACLED-DARFUR-VAC-2008-2021 (After Course Ended-for 2023 Portfolio).xlsx",
col_types = c("date", "numeric", "text",
"text", "text", "text", "text", "text",
"text", "text", "text", "text", "text",
"numeric", "numeric", "text",
"text", "numeric", "numeric"))
acled_short=ACLED_data[c("event_date","year","sub_event_type","actor1","inter1","admin1","admin2","location","latitude","longitude","attacks","fatalities")]
acled_2016 = subset(acled_short, year == 2016)
acled_2017 = subset(acled_short, year == 2017)
acled_2018 = subset(acled_short, year == 2018)
acled_2019 = subset(acled_short, year == 2019)
acled_2020 = subset(acled_short, year == 2020)
acled_2021 = subset(acled_short, year == 2021)
# Make objects special feature objects and set CRS to the original CRS of the darfur map shapefile -
acled_2016_sf <- st_as_sf(acled_2016, coords = c("longitude", "latitude"), crs = original_crs)
acled_2017_sf <- st_as_sf(acled_2017, coords = c("longitude", "latitude"), crs = original_crs)
acled_2018_sf <- st_as_sf(acled_2018, coords = c("longitude", "latitude"), crs = original_crs)
acled_2019_sf <- st_as_sf(acled_2019, coords = c("longitude", "latitude"), crs = original_crs)
acled_2020_sf <- st_as_sf(acled_2020, coords = c("longitude", "latitude"), crs = original_crs)
acled_2021_sf <- st_as_sf(acled_2021, coords = c("longitude", "latitude"), crs = original_crs)
# Transform the CRS to EPSG:20135
acled_2016_sf <- st_transform(acled_2016_sf, crs=CRS.new)
acled_2017_sf <- st_transform(acled_2017_sf, crs=CRS.new)
acled_2018_sf <- st_transform(acled_2018_sf, crs=CRS.new)
acled_2019_sf <- st_transform(acled_2019_sf, crs=CRS.new)
acled_2020_sf <- st_transform(acled_2020_sf, crs=CRS.new)
acled_2021_sf <- st_transform(acled_2021_sf, crs=CRS.new)
geo_pko <- readxl::read_excel("Geo-PKO-v-2-1-2023_portfolio-verified_bases_only-LATEST.xlsx")
# 2016
geo_pko_for_maps_16 = filter(geo_pko, year == 2016)
geo_pko_df_16 = geo_pko_for_maps_16[c("year","location","latitude", "longitude")]
geo_pko_16_avg.troops_per_base = geo_pko_for_maps_16 %>% group_by(location) %>% summarise(avg.troops = mean(no.troops, na.rm=TRUE))
geo_pko_df_16 = inner_join(geo_pko_16_avg.troops_per_base, geo_pko_df_16, by="location")
geo_pko_df_16 = distinct(geo_pko_df_16)
active_bases_2016_points = geo_pko_df_16
# 2017
geo_pko_for_maps_17 = filter(geo_pko, year == 2017)
geo_pko_df_17 = geo_pko_for_maps_17[c("year","location","latitude", "longitude")]
geo_pko_17_avg.troops_per_base = geo_pko_for_maps_17 %>% group_by(location) %>% summarise(avg.troops = mean(no.troops, na.rm=TRUE))
geo_pko_df_17 = inner_join(geo_pko_17_avg.troops_per_base, geo_pko_df_17, by="location")
geo_pko_df_17 = distinct(geo_pko_df_17)
active_bases_2017_points = geo_pko_df_17
# 2018
geo_pko_for_maps_18 = filter(geo_pko, year == 2018)
geo_pko_df_18 = geo_pko_for_maps_18[c("year","location","latitude", "longitude")]
geo_pko_18_avg.troops_per_base = geo_pko_for_maps_18 %>% group_by(location) %>% summarise(avg.troops = mean(no.troops, na.rm=TRUE))
geo_pko_df_18 = inner_join(geo_pko_18_avg.troops_per_base, geo_pko_df_18, by="location")
geo_pko_df_18 = distinct(geo_pko_df_18)
active_bases_2018_points = geo_pko_df_18
# 2019
geo_pko_for_maps_19 = filter(geo_pko, year == 2019)
geo_pko_df_19 = geo_pko_for_maps_19[c("year","location","latitude", "longitude")]
geo_pko_19_avg.troops_per_base = geo_pko_for_maps_19 %>% group_by(location) %>% summarise(avg.troops = mean(no.troops, na.rm=TRUE))
geo_pko_df_19 = inner_join(geo_pko_19_avg.troops_per_base, geo_pko_df_19, by="location")
geo_pko_df_19 = distinct(geo_pko_df_19)
active_bases_2019_points = geo_pko_df_19
# 2020
geo_pko_for_maps_20 = filter(geo_pko, year == 2020)
geo_pko_df_20 = geo_pko_for_maps_20[c("year","location","latitude", "longitude")]
geo_pko_20_avg.troops_per_base = geo_pko_for_maps_20 %>% group_by(location) %>% summarise(avg.troops = mean(no.troops, na.rm=TRUE))
geo_pko_df_20 = inner_join(geo_pko_20_avg.troops_per_base, geo_pko_df_20, by="location")
geo_pko_df_20 = distinct(geo_pko_df_20)
active_bases_2020_points = geo_pko_df_20
# Convert active UN bases for each given year to simple feature spatial objects
active_bases_2016_points_sf <- sf::st_as_sf(active_bases_2016_points, coords = c("longitude", "latitude"), crs = original_crs)
active_bases_2017_points_sf <- sf::st_as_sf(active_bases_2017_points, coords = c("longitude", "latitude"), crs = original_crs)
active_bases_2018_points_sf <- sf::st_as_sf(active_bases_2018_points, coords = c("longitude", "latitude"), crs = original_crs)
active_bases_2019_points_sf <- sf::st_as_sf(active_bases_2019_points, coords = c("longitude", "latitude"), crs = original_crs)
active_bases_2020_points_sf <- sf::st_as_sf(active_bases_2020_points, coords = c("longitude", "latitude"), crs = original_crs)
# Transform the CRS to EPSG:20135
active_bases_2016_points_sf <- st_transform(active_bases_2016_points_sf, crs=CRS.new)
active_bases_2017_points_sf <- st_transform(active_bases_2017_points_sf, crs=CRS.new)
active_bases_2018_points_sf <- st_transform(active_bases_2018_points_sf, crs=CRS.new)
active_bases_2019_points_sf <- st_transform(active_bases_2019_points_sf, crs=CRS.new)
active_bases_2020_points_sf <- st_transform(active_bases_2020_points_sf, crs=CRS.new)
# It is critical to replace all NA values for the variable `avg.troops` to 0
active_bases_2016_points_sf$avg.troops[is.na(active_bases_2016_points_sf$avg.troops)] <- 0
active_bases_2017_points_sf$avg.troops[is.na(active_bases_2017_points_sf$avg.troops)] <- 0
active_bases_2018_points_sf$avg.troops[is.na(active_bases_2018_points_sf$avg.troops)] <- 0
active_bases_2019_points_sf$avg.troops[is.na(active_bases_2019_points_sf$avg.troops)] <- 0
active_bases_2020_points_sf$avg.troops[is.na(active_bases_2020_points_sf$avg.troops)] <- 0
# Ensure all avg.troops variable values for the active_bases point objects are read as numbers
active_bases_2016_points_sf$avg.troops <- as.numeric(active_bases_2016_points_sf$avg.troops)
active_bases_2017_points_sf$avg.troops <- as.numeric(active_bases_2017_points_sf$avg.troops)
active_bases_2018_points_sf$avg.troops <- as.numeric(active_bases_2018_points_sf$avg.troops)
active_bases_2019_points_sf$avg.troops <- as.numeric(active_bases_2019_points_sf$avg.troops)
active_bases_2020_points_sf$avg.troops <- as.numeric(active_bases_2020_points_sf$avg.troops)
# Now, for active_bases_2016_points_sf - active_bases_2020_points_sf, filter these objects such that only the UN bases listed occur where the average number of troops is not 0. This ensures only active UN bases having UN troops present remain, which will then be plotted in the maps further below:
active_bases_2016_points_sf <- active_bases_2016_points_sf[active_bases_2016_points_sf$avg.troops != 0, ]
active_bases_2017_points_sf <- active_bases_2017_points_sf[active_bases_2017_points_sf$avg.troops != 0, ]
active_bases_2018_points_sf <- active_bases_2018_points_sf[active_bases_2018_points_sf$avg.troops != 0, ]
active_bases_2019_points_sf <- active_bases_2019_points_sf[active_bases_2019_points_sf$avg.troops != 0, ]
active_bases_2020_points_sf <- active_bases_2020_points_sf[active_bases_2020_points_sf$avg.troops != 0, ]
# At this point, I make "contains" spatial joins with R. See my comments in the code of Visual 6 for more understanding of the following code:
acled_2016_joined_sf <- sf::st_join(acled_2016_sf, join = st_within, left=FALSE, darfur_internal_sf)
acled_2017_joined_sf <- sf::st_join(acled_2017_sf, join = st_within, left=FALSE, darfur_internal_sf)
acled_2018_joined_sf <- sf::st_join(acled_2018_sf, join = st_within, left=FALSE, darfur_internal_sf)
acled_2019_joined_sf <- sf::st_join(acled_2019_sf, join = st_within, left=FALSE, darfur_internal_sf)
acled_2020_joined_sf <- sf::st_join(acled_2020_sf, join = st_within, left=FALSE, darfur_internal_sf)
acled_2021_joined_sf <- sf::st_join(acled_2021_sf, join = st_within, left=FALSE, darfur_internal_sf)
acled_2016_joined_sf$fatalities <- as.numeric(acled_2016_joined_sf$fatalities)
acled_2017_joined_sf$fatalities <- as.numeric(acled_2017_joined_sf$fatalities)
acled_2018_joined_sf$fatalities <- as.numeric(acled_2018_joined_sf$fatalities)
acled_2019_joined_sf$fatalities <- as.numeric(acled_2019_joined_sf$fatalities)
acled_2020_joined_sf$fatalities <- as.numeric(acled_2020_joined_sf$fatalities)
acled_2021_joined_sf$fatalities <- as.numeric(acled_2021_joined_sf$fatalities)
# Spatial joining data from the active_bases point objects to the darfur_internal shapefile. Refer back to my comments in the identical code in Visual 6 if you have any questions about the code:
darfur_map_contains_2016_bases_sf <- sf::st_join(darfur_internal_sf, join = st_contains, left=TRUE, active_bases_2016_points_sf)
darfur_map_contains_2017_bases_sf <- sf::st_join(darfur_internal_sf, join = st_contains, left=TRUE, active_bases_2017_points_sf)
darfur_map_contains_2018_bases_sf <- sf::st_join(darfur_internal_sf, join = st_contains, left=TRUE, active_bases_2018_points_sf)
darfur_map_contains_2019_bases_sf <- sf::st_join(darfur_internal_sf, join = st_contains, left=TRUE, active_bases_2019_points_sf)
darfur_map_contains_2020_bases_sf <- sf::st_join(darfur_internal_sf, join = st_contains, left=TRUE, active_bases_2020_points_sf)
# It is critical to replace all NA values for the variable `avg.troops` with 0 so that the choropleth map can be colored based on values:
darfur_map_contains_2016_bases_sf$avg.troops[is.na(darfur_map_contains_2016_bases_sf$avg.troops)] <- 0
darfur_map_contains_2017_bases_sf$avg.troops[is.na(darfur_map_contains_2017_bases_sf$avg.troops)] <- 0
darfur_map_contains_2018_bases_sf$avg.troops[is.na(darfur_map_contains_2018_bases_sf$avg.troops)] <- 0
darfur_map_contains_2019_bases_sf$avg.troops[is.na(darfur_map_contains_2019_bases_sf$avg.troops)] <- 0
darfur_map_contains_2020_bases_sf$avg.troops[is.na(darfur_map_contains_2020_bases_sf$avg.troops)] <- 0
# Next, for the variable `year`, any observations that have the value NA instead of 2016 for the 2016 map or 2020 for the 2020 map will be changed to the correct year.
darfur_map_contains_2016_bases_sf$year[is.na(darfur_map_contains_2016_bases_sf$year)] <- 2016
darfur_map_contains_2017_bases_sf$year[is.na(darfur_map_contains_2017_bases_sf$year)] <- 2017
darfur_map_contains_2018_bases_sf$year[is.na(darfur_map_contains_2018_bases_sf$year)] <- 2018
darfur_map_contains_2019_bases_sf$year[is.na(darfur_map_contains_2019_bases_sf$year)] <- 2019
darfur_map_contains_2020_bases_sf$year[is.na(darfur_map_contains_2020_bases_sf$year)] <- 2020
darfur_map_contains_2016_bases_sf$avg.troops <- as.numeric(darfur_map_contains_2016_bases_sf$avg.troops)
darfur_map_contains_2017_bases_sf$avg.troops <- as.numeric(darfur_map_contains_2017_bases_sf$avg.troops)
darfur_map_contains_2018_bases_sf$avg.troops <- as.numeric(darfur_map_contains_2018_bases_sf$avg.troops)
darfur_map_contains_2019_bases_sf$avg.troops <- as.numeric(darfur_map_contains_2019_bases_sf$avg.troops)
darfur_map_contains_2020_bases_sf$avg.troops <- as.numeric(darfur_map_contains_2020_bases_sf$avg.troops)
# I identify the second level administrative units in which each active UN base exists, and color the map by the average number of UN troops present during each year in a given administrative unit.
# For this set of maps, I focus on the administrative units specifically in West Darfur. I therefore used a polygon shapefile of Darfur, making it into a choropleth map in which second-level administrative units are colored based on the average number of UN troops stationed at UN bases in a given second level administrative region for a given year. I created 50 mile radius buffers emanating out from the coordinates of bases that were abandoned by the UN and calculated the number of attacks on civilians and the number of fatalities from such attacks within these buffers both in terms of the year before the bases were closed compared to the first year in which the bases were closed.
# We know that the UN bases withdrawn from West Darfur included the Forobaranga, Habila, and Tine bases in 2017, the El Sireaf, Masteri, Mournei, and Umm Barru bases in 2018, and the El Geneina base in 2019.
# I therefore created three faceted maps: one comparing attacks on civilians within 50 miles from the Forobaranga, Habila, and Tine bases in 2016 vs. 2017, one comparing attacks on civilians within 50 miles of the El Sireaf, Masteri, Mournei, and Umm Barru bases in 2017 vs. 2018, and one comparing attacks on civilians within 50 miles of the El Geneina base in 2018 vs. 2019. However, no bases in West Darfur were removed in 2020.
# The next steps will be to take the active_bases objects that are spatially joined to the darfur_internal map which contains second level administrative regions within it, and create choropleth maps based again on the total average number of troops in a given second level administrative region for the years in which I am comparing for 2016 vs. 2017, for 2017 vs. 2018, and for 2018 vs. 2019:
setwd("C:/Users/rsb84/Desktop/RB/COLUMBIA/QMSS/COURSES/Spring_2021/Data Visualization/End_project")
# Create a bounding box in WGS84
my_box <- rgeos::bbox2SP(n = 16.12054, s = 8.64132, w = 21.61368, e = 29.58313, proj4string = CRS("+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs"))
# Reproject the bounding box to EPSG:20135
my_box <- spTransform(my_box, CRS("+init=epsg:20135"))
fifty_miles_in_meters <- 50 * 1609.344
# UN Bases in West Darfur Closed in 2017:
closed_bases_west_2017 <- readxl::read_excel("closed_bases_west_2017-portfolio_2023.xlsx",
col_types = c("text", "text",
"numeric", "numeric"))
closed_bases_west_2017_sf=st_as_sf(closed_bases_west_2017, coords = c("longitude", "latitude"), crs = original_crs)
# UN Bases in West Darfur Closed in 2018:
closed_bases_west_2018 <- readxl::read_excel("closed_bases_west_2018-portfolio_2023.xlsx",
col_types = c("text", "text",
"numeric", "numeric"))
closed_bases_west_2018_sf=st_as_sf(closed_bases_west_2018, coords = c("longitude", "latitude"), crs = original_crs)
# UN Bases in West Darfur Closed in 2019:
closed_bases_west_2019 <- readxl::read_excel("closed_bases_west_2019-portfolio_2023.xlsx",
col_types = c("text", "text",
"numeric", "numeric"))
closed_bases_west_2019_sf=st_as_sf(closed_bases_west_2019, coords = c("longitude", "latitude"), crs = original_crs)
# Transform the following data to be plotted into a Projected CRS (i.e., EPSG:20135) that uses units of measurement like feet or meters rather than degrees:
closed_bases_west_2017_sf <- st_transform(closed_bases_west_2017_sf, CRS.new)
closed_bases_west_2018_sf <- st_transform(closed_bases_west_2018_sf, CRS.new)
closed_bases_west_2019_sf <- st_transform(closed_bases_west_2019_sf, CRS.new)
# Create buffer and union buffer objects around UN bases closed in West Darfur in 2017, 2018, and 2019:
# 2017
closed_bases_west_2017_buffers <- st_buffer(x=closed_bases_west_2017_sf, dist = fifty_miles_in_meters)
union_buffers_2017 <- st_union(closed_bases_west_2017_buffers)
# 2018
closed_bases_west_2018_buffers <- st_buffer(x=closed_bases_west_2018_sf, dist = fifty_miles_in_meters)
union_buffers_2018 <- st_union(closed_bases_west_2018_buffers)
# 2019
closed_bases_west_2019_buffers <- st_buffer(x=closed_bases_west_2019_sf, dist = fifty_miles_in_meters)
union_buffers_2019 <- st_union(closed_bases_west_2019_buffers)
troops_breaks <- c(0, 200, 400, 600, 800, 1000)
fatalities_breaks <- c(0, 10, 20, 30, 40, 50)
fatalities_labels <- c("0 to 10", "10 to 20", "20 to 30", "30 to 40", "40 to 50")
# Define thick black borders for first order administrative units
adm1_borders_col = "black" # Color for first order administrative borders
adm1_borders_lwd = 2 # Line width for first order administrative borders
# Currently, the darfur_map_contains_2016_bases, darfur_map_contains_2017_bases, darfur_map_contains_2018_bases, and darfur_map_contains_2019_bases sf map objects will display the geometries of their second order administrative districts. We want to create a second map of darfur that contains the names and geometries of the first order administrative districts; we can do this using the code below. This map will be used to provide thick black borders of North, South, East, West, and Central Darfur (which are Darfur's first order administrative districts) in the faceted tmap maps below even though each faceted maps will have their second order administrative districts be colored based on the average number of UN troops stationed within those respective second order administrative districts. Since all we are doing with this first order administrative district map is providing thick black boundaries, we can just use one of the second order administrative district maps in the code below
darfur_map_1st_order_adm <- darfur_map_contains_2016_bases_sf %>%
group_by(ADM1_EN) %>% # column with names of first order administrative districts
summarize(geometry = st_union(geometry)) %>% #column with geometries of the second order administrative districts
ungroup()
# You should put tmap_mode('plot') (for static maps) or tmap_mode('view') (for interactive maps) before creating the map with tm_shape() or any other tmap function. This sets the mode for all subsequent tmap functions until the mode is changed.
tmap_mode('plot')
layout1 <- tm_layout(
title = "Attacks on Civilians, Before vs. After the 2017\n Forobaranga and Habila Base Closures",
title.position = c("left","top"),
title.size=20, title.color="steelblue", fontface = 7,
legend.title.size = 1,
legend.title.color = "steelblue",
legend.text.size = 0.8,
legend.text.color = "steelblue",
legend.position = c(0.74,0.25),#c(horizontal, vertical)
legend.bg.color = "white",
legend.bg.alpha = 1,
bg.color="white",
frame=FALSE)
layout2 <- tm_layout(
title = "Attacks on Civilians, Before vs. After the 2018\n Masteri and Mournei Base Closures",
title.position = c("left","top"),
title.size=20, title.color="steelblue", fontface = 7,
legend.title.size = 1,
legend.title.color = "steelblue",
legend.text.size = 0.8,
legend.text.color = "steelblue",
legend.position = c(0.745,0.25),#c(horizontal, vertical)
legend.bg.color = "white",
legend.bg.alpha = 1,
bg.color="white",
frame=FALSE)
layout3 <- tm_layout(
title = "Attacks on Civilians, Before vs. After the 2019\n El Geneina Base Closure",
title.position = c("left","top"),
title.size=20, title.color="steelblue", fontface = 7,
legend.title.size = 1,
legend.title.color = "steelblue",
legend.text.size = 0.8,
legend.text.color = "steelblue",
legend.position = c(0.753,0.25),#c(horizontal, vertical)
legend.bg.color = "white",
legend.bg.alpha = 1,
bg.color="white",
frame=FALSE)
layout_no_title <- tm_layout(
title = "",
title.size=20, title.color="steelblue", fontface = 7,
legend.title.size = 1,
legend.title.color = "steelblue",
legend.text.size = 0.8,
legend.text.color = "steelblue",
legend.position = c(0.79,0.25),#c(horizontal, vertical)
legend.bg.color = "white",
legend.bg.alpha = 1,
bg.color="white",
frame=FALSE)
# 2016 vs. 2017 - First Set of Maps for Comparison
t_2016.1 <- tm_shape(darfur_map_contains_2016_bases_sf, bbox = my_box) +
tm_fill("avg.troops", title="Average Number\nof UN Troops", palette="Greens") +
tm_borders() +
tm_shape(darfur_map_1st_order_adm, bbox = my_box) +
tm_borders(col=adm1_borders_col, lwd=adm1_borders_lwd) +
tm_shape(closed_bases_west_2017_sf) +
tm_dots(size=0.5, col="steelblue") +
tm_shape(acled_2016_joined_sf) +
tm_bubbles(size="fatalities", scale = 2.7, col="red", alpha=0.3, jitter=0.05, title.size="Fatalities", breaks=c(0,10,20,30,40,50), sizes.legend=c((16/17)*5,(16/17)*10,(16/17)*15,(16/17)*20,(16/17)*25), sizes.legend.labels=c("10","20","30","40","50")) +
tm_shape(union_buffers_2017, projection = CRS.new) +
#tm_fill(col = "blue", alpha = 0.2) +
tm_borders(col = "blue", alpha = 1, lty = 1, lwd = 1.8) +
layout1 +
tm_add_legend(title="") +
tm_credits(text="2016", position=c("center", "bottom"), size=1.5)
t_2017.1 <- tm_shape(darfur_map_contains_2017_bases_sf, bbox = my_box) +
tm_fill("avg.troops", title="Average Number\nof UN Troops", palette="Greens") +
tm_borders() +
tm_shape(darfur_map_1st_order_adm, bbox = my_box) +
tm_borders(col=adm1_borders_col, lwd=adm1_borders_lwd) +
tm_shape(closed_bases_west_2017_sf) +
tm_dots(size=0.5, col="steelblue") +
tm_shape(acled_2017_joined_sf) +
tm_bubbles(size="fatalities", scale=1.25, col="red", alpha=0.3, jitter=0.05, title.size="Fatalities", breaks=c(0,10,20,30,40,50), sizes.legend=c(5,10,15,20,25), sizes.legend.labels=c("10","20","30","40","50")) +
tm_shape(union_buffers_2017, projection = CRS.new) +
#tm_fill(col = "blue", alpha = 0.2) +
tm_borders(col = "blue", alpha = 1, lty = 1, lwd = 1.8) +
layout_no_title +
tm_add_legend(title="") +
tm_credits(text="2017", position=c("center", "bottom"), size=1.5) +
tm_legend(show = FALSE)
# 2017 vs. 2018 - Second Set of Maps for Comparison
t_2017.2 <- tm_shape(darfur_map_contains_2017_bases_sf, bbox = my_box) +
tm_fill("avg.troops", title="Average Number\nof UN Troops", palette="Greens") +
tm_borders() +
tm_shape(darfur_map_1st_order_adm, bbox = my_box) +
tm_borders(col=adm1_borders_col, lwd=adm1_borders_lwd) +
tm_shape(closed_bases_west_2018_sf) +
tm_dots(size=0.5, col="steelblue") +
tm_shape(acled_2017_joined_sf) +
tm_bubbles(size="fatalities", scale=1.25, col="red", alpha=0.3, jitter=0.05, title.size="Fatalities", breaks=c(0,10,20,30,40,50), sizes.legend=c((37/32)*5,(37/32)*10,(37/32)*15,(37/32)*20,(37/32)*25), sizes.legend.labels=c("10","20","30","40","50")) +
tm_shape(union_buffers_2018, projection = CRS.new) +
#tm_fill(col = "blue", alpha = 0.2) +
tm_borders(col = "blue", alpha = 1, lty = 1, lwd = 1.8) +
layout2 +
tm_add_legend(title="") +
tm_credits(text="2017", position=c("center", "bottom"), size=1.5)
t_2018.2 <- tm_shape(darfur_map_contains_2018_bases_sf, bbox =my_box) +
tm_fill("avg.troops", title="Average Number\nof UN Troops", palette="Greens") +
tm_borders() +
tm_shape(darfur_map_1st_order_adm, bbox = my_box) +
tm_borders(col=adm1_borders_col, lwd=adm1_borders_lwd) +
tm_shape(closed_bases_west_2018_sf) +
tm_dots(size=0.5, col="steelblue") +
tm_shape(acled_2018_joined_sf) +
tm_bubbles(size="fatalities", scale=2, col="red", alpha=0.3, jitter=0.05, title.size="Fatalities", breaks=c(0,10,20,30,40,50), sizes.legend=c(10,20,30,40,50), sizes.legend.labels=c("10","20","30","40","50")) +
tm_shape(union_buffers_2018, projection = CRS.new) +
#tm_fill(col = "blue", alpha = 0.2) +
tm_borders(col = "blue", alpha = 1, lty = 1, lwd = 1.8) +
layout_no_title +
tm_add_legend(title="") +
tm_credits(text="2018", position=c("center", "bottom"), size=1.5) +
tm_legend(show = FALSE)
# 2018 v. 2019 - Third Set of Maps for Comparison
t_2018.3 <- tm_shape(darfur_map_contains_2018_bases_sf, bbox =my_box) +
tm_fill("avg.troops", title="Average Number\nof UN Troops", palette="Greens") +
tm_borders() +
tm_shape(darfur_map_1st_order_adm, bbox = my_box) +
tm_borders(col=adm1_borders_col, lwd=adm1_borders_lwd) +
tm_shape(closed_bases_west_2019_sf) +
tm_dots(size=0.5, col="steelblue") +
tm_shape(acled_2018_joined_sf)+
tm_bubbles(size="fatalities", scale=2, col="red", alpha=0.3, jitter=0.05, title.size="Fatalities", breaks=c(0,10,20,30,40,50), sizes.legend=c((27/61)*10,(27/61)*20,(27/61)*30,(27/61)*40,(27/61)*50), sizes.legend.labels=c("10","20","30","40","50")) +
tm_shape(union_buffers_2019, projection = CRS.new) +
#tm_fill(col = "blue", alpha = 0.2) +
tm_borders(col = "blue", alpha = 1, lty = 1, lwd = 1.8) +
layout3 +
tm_add_legend(title="") +
tm_credits(text="2018", position=c("center", "bottom"), size=1.5)
t_2019.3 <- tm_shape(darfur_map_contains_2019_bases_sf, bbox = my_box) +
tm_fill("avg.troops", title="Average Number\nof UN Troops", palette="Greens") +
tm_borders() +
tm_shape(darfur_map_1st_order_adm, bbox = my_box) +
tm_borders(col=adm1_borders_col, lwd=adm1_borders_lwd) +
tm_shape(closed_bases_west_2019_sf) +
tm_dots(size=0.5, col="steelblue") +
tm_shape(acled_2019_joined_sf) +
tm_bubbles(size="fatalities", scale=2, col="red", alpha=0.3, jitter=0.05, title.size="Fatalities", breaks=c(0,10,20,30,40,50), sizes.legend=c(5,10,15,20,25), sizes.legend.labels=c("10","20","30","40","50")) +
tm_shape(union_buffers_2019, projection = CRS.new) +
#tm_fill(col = "blue", alpha = 0.2) +
tm_borders(col = "blue", alpha = 1, lty = 1, lwd = 1.8) +
layout_no_title +
tm_add_legend(title="") +
tm_credits(text="2019", position=c("center", "bottom"), size=1.5) +
tm_legend(show = FALSE)
The first visual compares attack and fatality levels within 50 mi
radius buffers around the West Darfur UN bases in Forobaranga and Habila
that were closed in 2017 to 2016 levels. Visually, 2017 appears to show
almost the same number of attacks compared to 2016. But my calculations
reveal 30 attacks in 2016 compared to 27 in 2017, and 24 fatalities in
2016 compared to only 11 in 2017. Thus, civilian fatalities decreased by
54% after the base closures, suggesting that despite fewer UN troops the
closure of these bases did not adversely affect civilian security in the
area near the bases in the short term.
tmap_arrange(t_2016.1, t_2017.1, nrow = 1, ncol = 2, asp=1, outer.margins = 0)
In the third pair of maps (Darfur in 2018 vs. 2019), when comparing
the 50 mi radius buffer around the UN base in Habila that was withdrawn
in 2019, it visually appears there was an increase in both attacks and
fatalities from 2018 to 2019. Indeed, my calculations show that while
there were 13 attacks and 24 killings in 2018, attacks increased to 19
(a 46% increase) and fatalities increased to 44 (an 83% increase) in
2019.
tmap_arrange(t_2018.3, t_2019.3, nrow = 1, ncol = 2, asp=1, outer.margins = 0)
# CALCULATNG ATTACKS ON CIVILIANS & FATALITIES PER YEAR INSIDE 50 MILE RADIUS BUFFERS AROUND BASES CLOSED IN 2017, 2018, and 2019
# length() calculates the number of civilian attacks
# sum() calculates the number of fatalities from these attacks
# Calculating attacks (length) and fatalities (sum) in 2016 - Buffer 2017
# Calculating attacks (length) and fatalities (sum) in 2016 - Buffer 2017
fatality_sum_2016.buffer_2017 = sf::st_filter(acled_2016_joined_sf, union_buffers_2017, .predicate = st_within)
fatality_sum_2016.buffer_2017$fatalities = as.numeric(fatality_sum_2016.buffer_2017$fatalities)
attacks_2016_buffer_2017 <- length(fatality_sum_2016.buffer_2017$fatalities)
deaths_2016_buffer_2017 <- sum(fatality_sum_2016.buffer_2017$fatalities)
# Calculating attacks (length) and fatalities (sum) in 2017 - buffer 2017
fatality_sum_2017.buffer_2017 = sf::st_filter(acled_2017_joined_sf, union_buffers_2017, .predicate = st_within)
attacks_2017_buffer_2017 <- length(fatality_sum_2017.buffer_2017$fatalities)
deaths_2017_buffer_2017 <- sum(fatality_sum_2017.buffer_2017$fatalities)
# Calculating attacks (length) and fatalities (sum) in 2018 - buffer 2017
fatality_sum_2018.buffer_2017 = sf::st_filter(acled_2018_joined_sf, union_buffers_2017, .predicate = st_within)
attacks_2018_buffer_2017 <- length(fatality_sum_2018.buffer_2017$fatalities)
deaths_2018_buffer_2017 <- sum(fatality_sum_2018.buffer_2017$fatalities)
# Calculating attacks (length) and fatalities (sum) in 2019 - buffer 2017
fatality_sum_2019.buffer_2017 = sf::st_filter(acled_2019_joined_sf, union_buffers_2017, .predicate = st_within)
attacks_2019_buffer_2017 <- length(fatality_sum_2019.buffer_2017$fatalities)
deaths_2019_buffer_2017 <- sum(fatality_sum_2019.buffer_2017$fatalities)
# Calculating attacks (length) and fatalities (sum) in 2020 - buffer 2017
fatality_sum_2020.buffer_2017 = sf::st_filter(acled_2020_joined_sf, union_buffers_2017, .predicate = st_within)
attacks_2020_buffer_2017 <- length(fatality_sum_2020.buffer_2017$fatalities)
deaths_2020_buffer_2017 <- sum(fatality_sum_2020.buffer_2017$fatalities)
# Calculating attacks (length) and fatalities (sum) in 2021 - buffer 2017
fatality_sum_2021.buffer_2017 = sf::st_filter(acled_2021_joined_sf, union_buffers_2017, .predicate = st_within)
fatality_sum_2021.buffer_2017$fatalities = as.numeric(fatality_sum_2021.buffer_2017$fatalities)
attacks_2021_buffer_2017 <- length(fatality_sum_2021.buffer_2017$fatalities)
deaths_2021_buffer_2017 <- sum(fatality_sum_2021.buffer_2017$fatalities)
# Calculating attacks (length) and fatalities (sum) in 2016 - Buffer in 2018
fatality_sum_2016.buffer_2018 = sf::st_filter(acled_2016_joined_sf, union_buffers_2018, .predicate = st_within)
attacks_2016_buffer_2018 <- length(fatality_sum_2016.buffer_2018$fatalities)
deaths_2016_buffer_2018 <- sum(fatality_sum_2016.buffer_2018$fatalities)
# Calculating attacks (length) and fatalities (sum) in 2017 - Buffer in 2018
fatality_sum_2017.buffer_2018 = sf::st_filter(acled_2017_joined_sf, union_buffers_2018, .predicate = st_within)
attacks_2017_buffer_2018 <- length(fatality_sum_2017.buffer_2018$fatalities)
deaths_2017_buffer_2018 <- sum(fatality_sum_2017.buffer_2018$fatalities)
# Calculating attacks (length) and fatalities (sum) in 2018 - Buffer in 2018
fatality_sum_2018.buffer_2018 = sf::st_filter(acled_2018_joined_sf, union_buffers_2018, .predicate = st_within)
attacks_2018_buffer_2018 <- length(fatality_sum_2018.buffer_2018$fatalities)
deaths_2018_buffer_2018 <- sum(fatality_sum_2018.buffer_2018$fatalities)
# Calculating attacks (length) and fatalities (sum) in 2019 - Buffer in 2018
fatality_sum_2019.buffer_2018 = sf::st_filter(acled_2019_joined_sf, union_buffers_2018, .predicate = st_within)
attacks_2019_buffer_2018 <- length(fatality_sum_2019.buffer_2018$fatalities)
deaths_2019_buffer_2018 <- sum(fatality_sum_2019.buffer_2018$fatalities)
# Calculating attacks (length) and fatalities (sum) in 2020 - Buffer in 2018
fatality_sum_2020.buffer_2018 = sf::st_filter(acled_2020_joined_sf, union_buffers_2018, .predicate = st_within)
attacks_2020_buffer_2018 <- length(fatality_sum_2020.buffer_2018$fatalities)
deaths_2020_buffer_2018 <- sum(fatality_sum_2020.buffer_2018$fatalities)
# Calculating attacks (length) and fatalities (sum) in 2021 - Buffer in 2018
fatality_sum_2021.buffer_2018 = sf::st_filter(acled_2021_joined_sf, union_buffers_2018, .predicate = st_within)
fatality_sum_2021.buffer_2018$fatalities=as.numeric(fatality_sum_2021.buffer_2018$fatalities)
attacks_2021_buffer_2018 <- length(fatality_sum_2021.buffer_2018$fatalities)
deaths_2021_buffer_2018 <- sum(fatality_sum_2021.buffer_2018$fatalities)
# Calculating attacks (length) and fatalities (sum) in 2016 - Buffer 2019
fatality_sum_2016.buffer_2019 = sf::st_filter(acled_2016_joined_sf, union_buffers_2019, .predicate = st_within)
attacks_2016_buffer_2019 <- length(fatality_sum_2016.buffer_2019$fatalities)
deaths_2016_buffer_2019 <- sum(fatality_sum_2016.buffer_2019$fatalities)
# Calculating attacks (length) and fatalities (sum) in 2017 - Buffer 2019
fatality_sum_2017.buffer_2019 = sf::st_filter(acled_2017_joined_sf, union_buffers_2019, .predicate = st_within)
attacks_2017_buffer_2019 <- length(fatality_sum_2017.buffer_2019$fatalities)
deaths_2017_buffer_2019 <- sum(fatality_sum_2017.buffer_2019$fatalities)
# Calculating attacks (length) and fatalities (sum) in 2018 - Buffer 2019
fatality_sum_2018.buffer_2019 = sf::st_filter(acled_2018_joined_sf, union_buffers_2019, .predicate = st_within)
attacks_2018_buffer_2019 <- length(fatality_sum_2018.buffer_2019$fatalities)
deaths_2018_buffer_2019 <- sum(fatality_sum_2018.buffer_2019$fatalities)
# Calculating attacks (length) and fatalities (sum) in 2019 - Buffer 2019
fatality_sum_2019.buffer_2019 = sf::st_filter(acled_2019_joined_sf, union_buffers_2019, .predicate = st_within)
attacks_2019_buffer_2019 <- length(fatality_sum_2019.buffer_2019$fatalities)
deaths_2019_buffer_2019 <- sum(fatality_sum_2019.buffer_2019$fatalities)
# Calculating attacks (length) and fatalities (sum) in 2020 - Buffer 2019
fatality_sum_2020.buffer_2019 = sf::st_filter(acled_2020_joined_sf, union_buffers_2019, .predicate = st_within)
attacks_2020_buffer_2019 <- length(fatality_sum_2020.buffer_2019$fatalities)
deaths_2020_buffer_2019 <- sum(fatality_sum_2020.buffer_2019$fatalities)
# Calculating attacks (length) and fatalities (sum) in 2021 - Buffer 2019
fatality_sum_2021.buffer_2019 = sf::st_filter(acled_2021_joined_sf, union_buffers_2019, .predicate = st_within)
attacks_2021_buffer_2019 <- length(fatality_sum_2021.buffer_2019$fatalities)
deaths_2021_buffer_2019 <- sum(fatality_sum_2021.buffer_2019$fatalities)
The table below shows calculations of civilian attacks and
fatalities in West Darfur from 2016 - 2021 within 50 mi of the UN bases
closed from 2017-2019. Notably, violence was highest in areas around the
bases closed in 2018 and lowest around those closed in 2017 for most of
these years; the 2018 closure areas were clearly already violence-prone
before their bases were closed.
Still, in 2019, violence increased in areas around the bases closed
in 2018 and 2019, and violence increased in 2021 in areas around bases
closed in 2017, 2018, and 2019. E.g., in the year 2021, the 2017 closure
areas saw 15 attacks and 46 fatalities (44% decrease in attacks, 318%
increase in fatalities compared to the year 2017), the 2018 closure
areas had 53 attacks and 133 fatalities (112% increase in attacks, 329%
increase in fatalities compared to the year 2018), and the 2019 closure
areas experienced 41 attacks and 124 fatalities (116% increase in
attacks, 182% increase in fatalities compared to the year 2019).
As theorized in Visual 5, we can plainly see that in 2019 and 2021
in West Darfur, areas around closed UN bases showed high civilian
fatality rates compared to the number of attacks. In 2019, areas with
bases closed in 2018 had 23 attacks and 67 fatalities (2.91 fatalities
per attack), and the area around the base closed in 2019 saw 19 attacks
and 44 fatalities (2.32 fatalities per attack). In 2021, areas where UN
bases closed in 2017, 2018, and 2019 experienced rates of 3.07, 2.51,
and 3.02 fatalities per attack, respectively. Except for the year 2018
around the base later closed in 2019, there are no other cases in the
years analyzed which approach 2 or more fatalities per attack.
library(kableExtra)
# Create a dataframe
df <- data.frame(
Attacks1 = c(attacks_2016_buffer_2017, attacks_2017_buffer_2017, attacks_2018_buffer_2017, attacks_2019_buffer_2017, attacks_2020_buffer_2017, attacks_2021_buffer_2017),
Fatalities1 = c(deaths_2016_buffer_2017, deaths_2017_buffer_2017, deaths_2018_buffer_2017, deaths_2019_buffer_2017, deaths_2020_buffer_2017, deaths_2021_buffer_2017),
Attacks2 = c(attacks_2016_buffer_2018, attacks_2017_buffer_2018, attacks_2018_buffer_2018, attacks_2019_buffer_2018, attacks_2020_buffer_2018, attacks_2021_buffer_2018),
Fatalities2 = c(deaths_2016_buffer_2018, deaths_2017_buffer_2018, deaths_2018_buffer_2018, deaths_2019_buffer_2018, deaths_2020_buffer_2018, deaths_2021_buffer_2018),
Attacks3 = c(attacks_2016_buffer_2019, attacks_2017_buffer_2019, attacks_2018_buffer_2019, attacks_2019_buffer_2019, attacks_2020_buffer_2019, attacks_2021_buffer_2019),
Fatalities3 = c(deaths_2016_buffer_2019, deaths_2017_buffer_2019, deaths_2018_buffer_2019, deaths_2019_buffer_2019, deaths_2020_buffer_2019, deaths_2021_buffer_2019),
row.names = c("2016", "2017", "2018", "2019", "2020", "2021")
)
# Since dataframes in R cannot have duplicate column names, this code below changes the column names just for the display to allow for duplicate column names under "2017 Closed Base Areas", "2018 Closed Base Areas", and "2019 Closed Base Areas"
df_display <- df
names(df_display) <- rep(c("Attacks", "Fatalities"), 3)
# Below is the code for a red cell-scaled table in which the degree of redness in each cell depends on how large or small the integer values are in comparison to all of the other integers in the table. The value of having this type of table is that it quickly helps the reader understand trends by seeing which cells, columns, and/or rows are most important to look at. The font color is white for cell values > the 8th decile, and black otherwise. Through trial and error, I found that using such a high threshold helped the integer values inside the cells with both the darker as well as lighter shades of red to be clearly readable. A lower threshold will result in difficulty reading some integer values.
library(scales)
# Get min, max, and 3rd quantile values for the entire dataframe for scaling
min_val <- min(df)
max_val <- max(df)
quantile_val <- quantile(unlist(df), 0.8) # calculate the 8th decile from the original numeric dataframe
df_display[] <- lapply(df_display, function(x) {
if(is.numeric(x)) {
cell_spec(x, "html",
color = ifelse(x > quantile_val, "white", "black"),
background = scales::gradient_n_pal(c("white", "red"))(scales::rescale(x, from = c(min_val, max_val))))
} else {
x
}
})
# Code for the table
kable_output <- kbl(df_display, format = "html", escape = FALSE, align = 'c') %>%
kable_styling(bootstrap_options = c("striped", "hover"), full_width = F) %>%
add_header_above(c(" " = 1, "Area around 2017 Closed Bases" = 2,
"Area around 2018 Closed Bases" = 2,
"Area around 2019 Closed Bases" = 2))
# Center each column name, column contents, and each header
kable_output <- kable_output %>%
column_spec(1, bold = TRUE) %>%
column_spec(2, extra_css = "text-align: center;") %>%
column_spec(3, extra_css = "text-align: center;", border_right = TRUE) %>%
column_spec(4, extra_css = "text-align: center;") %>%
column_spec(5, extra_css = "text-align: center;", border_right = TRUE) %>%
column_spec(6, extra_css = "text-align: center;") %>%
column_spec(7, extra_css = "text-align: center;", border_right = TRUE) %>%
row_spec(0, extra_css = "width:150px;") # Ensures the headers are centered by having sufficient space to separate them
kable_output
|
Area around 2017 Closed Bases
|
Area around 2018 Closed Bases
|
Area around 2019 Closed Bases
|
|
Attacks
|
Fatalities
|
Attacks
|
Fatalities
|
Attacks
|
Fatalities
|
2016
|
30
|
24
|
66
|
42
|
32
|
25
|
2017
|
27
|
11
|
44
|
21
|
16
|
7
|
2018
|
12
|
9
|
25
|
31
|
13
|
24
|
2019
|
9
|
4
|
23
|
67
|
19
|
44
|
2020
|
8
|
4
|
41
|
35
|
28
|
30
|
2021
|
15
|
46
|
53
|
133
|
41
|
124
|
Next, in Visual 8 I will create similar maps to the ones shown here
(but with respect to South Darfur).
# Get the current page number from the file name
current_page <- as.numeric(str_extract(knitr::current_input(), "\\d+"))
# Set the total number of pages
total_pages <- 9
# Generate the URLs for the previous and next pages
previous_page <- ifelse(current_page > 1, paste0("visual_", current_page - 1, "-darfur_violence-code_included.html"), NA)
next_page <- ifelse(current_page < total_pages, paste0("visual_", current_page + 1, "-darfur_violence-code_included.html"), NA)