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)

# I removed the code for "Next Page" both from the R code above and from the html code below because this is the last page


The interactive plot below examines South Darfur and West Darfur with respect to the proportion of all civilian killings carried out by each type of perpetrator.


# 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.

library(tidyverse)
library(ggplot2)
library(ggthemes)
library(plotly)

setwd("C:/Users/rsb84/Desktop/RB/COLUMBIA/QMSS/COURSES/Spring_2021/Data Visualization/End_project")

ACLED_data <- readxl::read_excel("ACLED-DARFUR-VAC-2008-2021-LATEST-inter1_integers_version.xlsx", 
     col_types = c("date", "numeric", "text", 
         "text", "text", "text", "text", "text", 
         "text", "text", "text", "text", "text", 
         "numeric", "numeric", "text", "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_2021_west_south = subset(acled_short, acled_short$year != 2008 & acled_short$year != 2009 & acled_short$year != 2010 & acled_short$year != 2011 & acled_short$year != 2012 & acled_short$year != 2013 & acled_short$year != 2014 & acled_short$year != 2015 & acled_short$admin1 != 'North Darfur'  & acled_short$admin1 != 'East Darfur' & acled_short$admin1 != 'Central Darfur')

fatalities_by_region_year_actor=acled_2016_2021_west_south %>% group_by(admin1, year, inter1) %>% tally(fatalities)


# The ACLED dataset lists the values of the column inter1 as being between 1 and 8. These values have a specific meaning. 1 corresponds to "State Forces", 2 to "Rebel Groups", 3 to "Political Militias", 4 to "Identity Militias", 5 to "Rioters", 6 to "Protesters", 7 to "Civilians", and 8 to "External/Other Forces". However, I inspected the dataframe acled_2016_2021_west_south from which the grouped dataframe fatalities_by_region_year_actor was created, and found there were no values for the column inter1 between 4 and 8. I.e., only "State Forces", "Political Militias", "Identity Militias", "Rebel Groups", and "External/Other Forces" were responsible for attacks on civilians in the aforementioned dataframes. The code below ensures that these labels for inter1 will appear in the following order on legends of any tables and/or plots: "State Forces", "Political Militias", "Identity Militias", "Rebel Groups", "External/Other Forces"

df2 <- fatalities_by_region_year_actor %>% 
  mutate(pct = prop.table(n) * 100) %>%
  mutate(inter1 = factor(inter1, levels = c(1,3,4,2,8), labels = c("State Forces", "Political Militias", "Identity Militias", "Rebel Groups", "External/Other Forces"))) %>% #This controls the order of the armed groups on the legend  
  mutate(Percent = round(pct, digits = 1),
         Perpetrator = inter1,
         Year = year)

# Note: If the above string values were already in the column inter1 in the original excel file in place of integer values, the code to produce exactly the same order as the order above for legends of any tables or plots based on the grouped dataframe df2 would have been the following instead:

# df2 <- fatalities_by_region_year_actor %>%
#   mutate(pct = prop.table(n) * 100) %>%
#   mutate(inter1 = factor(inter1, levels = c(""State Forces", "Political Militias", "Identity Militias", "Rebel Groups", "External/Other Forces"))) %>% #This controls the order of the armed groups on the legend
#   mutate(Percent = round(pct, digits = 1),
#          Perpetrator = inter1,
#          Year = year)

# Define colors corresponding to each group
colors <- c("State Forces" = "maroon1",
            "Political Militias" = "deepskyblue1",
            "Identity Militias" = "peru",
            "Rebel Groups" = "gray65",
            "External/Other Forces" = "black")

# Specify the custom labels for the y-axis
custom_labels <- c("0", "25", "50", "75", "100")

# Create the plot
gg <- ggplot(df2, aes(x = Year, y = Percent, fill = Perpetrator)) +
  geom_col(position = "fill", width = 0.8, size = 1, alpha = 0.7) +
  scale_fill_manual(values = colors, 
                    breaks = c("State Forces", "Political Militias", "Identity Militias", "Rebel Groups", "External/Other Forces"),
                    labels = c("State Forces", "Political Militias", "Identity Militias", "Rebel Groups", "External/Other Forces")) +
  scale_y_continuous(breaks = seq(0, 1, by = 0.25), labels = custom_labels) +  # Set custom breaks and labels for y-axis
  scale_x_continuous(breaks = seq(min(df2$Year), max(df2$Year), by = 1)) +  # Ensure years are displayed without gaps
  theme_wsj() +
  theme(legend.position = "top",
        title = element_text(size = 16, color = "steelblue", face = 'bold'),
        axis.title.x = element_blank(),
        axis.title.y = element_blank(),
        axis.text.x = element_text(size = 12),
        axis.text.y = element_text(size = 14),
        strip.text.x = element_text(size=16, face = 'bold'),
        legend.text=element_text(size=13)) +
  labs(title = "Perpetrators' Share of Civilian Killings (2016-2021)",
       subtitle = "Jan. 2016 - Dec. 2021",
       caption = "") +
  guides(fill = guide_legend(title = "")) +
  facet_wrap(~ admin1)

ggplotly(gg, height = 600, width = 850)


ACLED’s 2021 Codebook clarifies that “State Forces” are recognized government function performers, including military and police (pg. 21). It distinguishes “Political Militias” as groups formed for political objectives through violence, aiming to influence governance without overthrowing national power. These militias, often backed by political elites, work with governments or other influential groups for defined goals (pp. 22-23). They may associate with specific identity communities but are distinguished from “identity militias” due to their broader political goals (pg. 23).


As shown in the above visualizations, in almost all cases between 2016 and 2021 in both South Darfur and West Darfur, only state forces, political militias, or identity militias killed civilians.


In 2018, state forces accounted for 38% and 43% of civilian killings in South Darfur and West Darfur respectively, but these figures significantly decreased in the following years. This decline hints at possible growing political will to avoid obvious state-sponsored killings, potentially influenced by the governance changes following the December 2018 to September 2019 revolution. The revolution ousted longtime dictator Omar al-Bashir and established a joint civilian-military transitional government.


However, civilian killings by political militias in South Darfur rose from 33% in 2018 to 57% in 2019, and in West Darfur, they increased from 4% in 2019 to 68% in 2020. A personal examination of the raw data revealed that all of these killings by political militias are coded as having been committed by “Unidentified Armed Group (Sudan)”. I.e., because their identity could not be established they could not be directly linked to either the government or the opposition. Thus, it is at least possible state-led civilian killings may have continued, but were executed by unidentified political militias loyal to the state, enabling state leaders to maintain plausible deniability.


Troublingly, as civilian killings by state forces declined, those by identity militias surged. In South Darfur, identity militia killings rose from 23% in 2019 to 77% in 2020, and in West Darfur, from 50% in 2018 to 85% in 2019. Although this share dropped to 26% in 2020, it dramatically increased to 93% in 2021 with the complete withdrawal of the mission.


The spike in killings by identity militias as UN troops withdrew indicates that the Sudanese government, despite a possible increase in political will to avoid obvious civilian killings, may have lacked the capacity and/or desire to fill emerging power vacuums and prevent such violence.


The second interactive table displays the annual number of civilian killings by perpetrator type, not their proportion. It shows that until 2019, South Darfur had more fatalities from identity militias than West Darfur. However, this trend shifted in 2019 with 39 identity militia killings (up from 15 the previous year) in West Darfur, and dramatically so in 2021 with 144 such killings. The table also indicates a significant decrease in the overall number of killings by state forces, especially in South Darfur after 2018.


#Delete when done
filtered_data_for_inspection <- acled_2016_2021_west_south %>%
  filter(
    (admin1 == "South Darfur" & (year == 2018 | year == 2019)) |
    (admin1 == "West Darfur" & (year == 2019 | year == 2020))
  ) %>%
    mutate(Perpetrator = factor(inter1, 
                                levels = c(1, 2, 3, 4, 5, 6, 7, 8), 
                                labels = c("State Forces", "Rebel Groups", "Political Militias", "Identity Militias", "Rioters", "Protesters", "Civilians", "External/Other Forces"))) %>%
    select(-inter1) %>%
    filter(Perpetrator == "Political Militias") %>%
    mutate(Year = year,
         Actor = actor1) %>%
    group_by(admin1, Year, Perpetrator, Actor) %>%                       # Group by admin1, Year, Perpetrator, and Actor
    summarise(
      Fatalities = sum(fatalities, na.rm = TRUE),   # Sum fatalities, removing NA values
      Attacks = sum(attacks, na.rm = TRUE),         # Sum attacks, removing NA values
      .groups = 'drop'                              # Drop the grouping structure afterwards
    ) %>%
    group_by(admin1, Year, Perpetrator, Actor) %>%  # Regroup by 
    arrange(desc(Fatalities), .by_group = TRUE)
    


df3 <- fatalities_by_region_year_actor %>% 
  mutate(Fatalities = n) %>%
  mutate(Perpetrator = factor(inter1, levels = c(1,3,4,2,8), labels = c("State Forces", "Political Militias", "Identity Militias", "Rebel Groups", "External/Other Forces"))) %>%
  mutate(Year = year)
 
# Define colors corresponding to each group
colors <- c("State Forces" = "maroon1",
            "Political Militias" = "deepskyblue1",
            "Identity Militias" = "peru",
            "Rebel Groups" = "gray65",
            "External/Other Forces" = "black")

# Specify the custom labels for the y-axis
#custom_labels <- c("0", "25", "50", "75", "100")

# Create the plot
gg2 <- ggplot(df3, aes(x = Year, y = Fatalities, fill = Perpetrator)) +
  geom_col(position = "stack", width = 0.8, size = 1, alpha = 0.7) +
  scale_fill_manual(values = colors, 
                    breaks = c("State Forces", "Political Militias", "Identity Militias", "Rebel Groups", "External/Other Forces"),
                    labels = c("State Forces", "Political Militias", "Identity Militias", "Rebel Groups", "External/Other Forces")) +
#  scale_y_continuous(breaks = seq(0, 1, by = 0.25), labels = custom_labels) +  # Set custom breaks and labels for y-axis
  scale_y_continuous(breaks = seq(min(df3$n), max(df3$n), by = 15)) +
  scale_x_continuous(breaks = seq(min(df3$year), max(df3$year), by = 1)) +  # Ensure years are displayed without gaps
  theme_wsj() +
  theme(legend.position = "top",
        title = element_text(size = 16, color = "steelblue", face = 'bold'),
        axis.title.x = element_blank(),
        axis.title.y = element_blank(),
        axis.text.x = element_text(size = 12),
        axis.text.y = element_text(size = 14),
        strip.text.x = element_text(size=16, face = 'bold'),
        legend.text=element_text(size=13)) +
  labs(title = "Perpetrators' Number of Civilian Killings (2016-2021)",
       subtitle = "Jan. 2016 - Dec. 2021",
       caption = "") +
  guides(fill = guide_legend(title = "")) +
  facet_wrap(~ admin1)

ggplotly(gg2, height = 600, width = 850)


fatalities_region_year_identity_militias = acled_2016_2021_west_south %>%
  filter(inter1 == "Identity Militias") %>%
  group_by(admin1, year, actor1) %>%
  tally(fatalities)


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("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_short = ACLED_data[c("event_date","admin1","year","sub_event_type","actor1","inter1","location","latitude","longitude","attacks","fatalities")] %>%
    mutate(Perpetrator = factor(inter1, 
                                levels = c(1, 2, 3, 4, 5, 6, 7, 8), 
                                labels = c("State Forces", "Rebel Groups", "Political Militias", "Identity Militias", "Rioters", "Protesters", "Civilians", "External/Other Forces"))) #%>%
    #select(-inter1)


acled <- acled_short %>% 
  mutate(inter1 = factor(inter1, levels = c(1,3,4,2,8), labels = c("State Forces", "Political Militias", "Identity Militias", "Rebel Groups", "External/Other Forces"))) %>% #This assigns the specified armed groups in the labels argument to the integer values in the levels argument. It also controls the order of the armed groups on any legends  
  mutate(Perpetrator = inter1,
         Year = year,
         Actor = actor1)


acled_2016 = subset(acled, year == 2016)
acled_2017 = subset(acled, year == 2017)
acled_2018 = subset(acled, year == 2018)
acled_2019 = subset(acled, year == 2019)
acled_2020 = subset(acled, year == 2020)
acled_2021 = subset(acled, 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)

# 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)


fifty_miles_in_meters <- 50 * 1609.344

# Closed South Darfur Bases between 2017 - 2019
# UN Bases in South Darfur Closed in 2017:
closed_bases_south_2017 <- readxl::read_excel("closed_bases_south_2017-portfolio_2023.xlsx", 
     col_types = c("text", "text", 
         "numeric", "numeric"))
closed_bases_south_2017_sf=st_as_sf(closed_bases_south_2017, coords = c("longitude", "latitude"), crs = original_crs)

# UN Bases in South Darfur Closed in 2018:
closed_bases_south_2018 <- readxl::read_excel("closed_bases_south_2018-portfolio_2023.xlsx", 
     col_types = c("text","text", 
         "numeric", "numeric"))
closed_bases_south_2018_sf=st_as_sf(closed_bases_south_2018, coords = c("longitude", "latitude"), crs = original_crs)

# UN Bases in South Darfur Closed in 2019:
closed_bases_south_2019 <- readxl::read_excel("closed_bases_south_2019-portfolio_2023.xlsx", 
     col_types = c("text", "text", 
         "numeric", "numeric"))
closed_bases_south_2019_sf=st_as_sf(closed_bases_south_2019, coords = c("longitude", "latitude"), crs = original_crs)

# Closed West Darfur Bases between 2017 - 2019
# 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 of meters rather than degrees

closed_bases_south_2017_sf <- st_transform(closed_bases_south_2017_sf, CRS.new)
closed_bases_south_2018_sf <- st_transform(closed_bases_south_2018_sf, CRS.new)
closed_bases_south_2019_sf <- st_transform(closed_bases_south_2019_sf, CRS.new)

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 objects around UN bases closed in South Darfur in 2017, 2018, and 2019:

# South Darfur
# 2017
closed_bases_south_2017_buffers <- st_buffer(x=closed_bases_south_2017_sf, dist =  fifty_miles_in_meters)
union_buffers_south.2017 <- st_union(closed_bases_south_2017_buffers)

# 2018
closed_bases_south_2018_buffers <- st_buffer(x=closed_bases_south_2018_sf, dist =  fifty_miles_in_meters)
union_buffers_south.2018 <- st_union(closed_bases_south_2018_buffers)

# 2019
closed_bases_south_2019_buffers <- st_buffer(x=closed_bases_south_2019_sf, dist =  fifty_miles_in_meters)
union_buffers_south.2019 <- st_union(closed_bases_south_2019_buffers)


# West Darfur
# 2017
closed_bases_west_2017_buffers <- st_buffer(x=closed_bases_west_2017_sf, dist =  fifty_miles_in_meters)
union_buffers_west.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_west.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_west.2019 <- st_union(closed_bases_west_2019_buffers)


# CALCULATNG ATTACKS ON CIVILIANS & FATALITIES PER YEAR INSIDE 50 MILE RADIUS buffers AROUND SOUTH DARFUR BASES CLOSED IN 2017, 2018, and 2019

# length() calculates the number of civilian attacks
# sum() calculates the number of fatalities from these attacks


acled_data_2016.south_buffers_2017 = sf::st_filter(acled_2016_joined_sf, union_buffers_south.2017, .predicate = st_within)


acled_data_2017.south_buffers_2017 = sf::st_filter(acled_2017_joined_sf, union_buffers_south.2017, .predicate = st_within)


acled_data_2018.south_buffers_2017 = sf::st_filter(acled_2018_joined_sf, union_buffers_south.2017, .predicate = st_within)


acled_data_2019.south_buffers_2017 = sf::st_filter(acled_2019_joined_sf, union_buffers_south.2017, .predicate = st_within)


acled_data_2020.south_buffers_2017 = sf::st_filter(acled_2020_joined_sf, union_buffers_south.2017, .predicate = st_within)


acled_data_2021.south_buffers_2017 = sf::st_filter(acled_2021_joined_sf, union_buffers_south.2017, .predicate = st_within)


acled_data_all_years.south_buffers_2017 = rbind(acled_data_2016.south_buffers_2017, acled_data_2017.south_buffers_2017, acled_data_2018.south_buffers_2017, acled_data_2019.south_buffers_2017, acled_data_2020.south_buffers_2017, acled_data_2021.south_buffers_2017)


# Filtering, transforming, summarizing, and then retaining top 2 rows for each year based on fatalities
violence_per_identity_militia_actor.south_buffers_2017 <- acled_data_all_years.south_buffers_2017 %>%
  filter(Perpetrator == "Identity Militias", admin1 == "South Darfur") %>%  # Keep only rows where Perpetrator is "Identity Militias" and where admin1 is "South Darfur"
  mutate(Year = year,                      
         Actor = actor1) %>%
  group_by(Year, Actor) %>%                       # Group by Year and Actor
  summarise(
    Fatalities = sum(fatalities, na.rm = TRUE),   # Sum fatalities, removing NA values
    Attacks = sum(attacks, na.rm = TRUE),         # Sum attacks, removing NA values
    .groups = 'drop'                              # Drop the grouping structure afterwards
  ) %>%
  mutate(Buffers = "2017 Closed Base Areas") %>% # Add new column denoting the buffer
  group_by(Year) %>%                             # Regroup by Year only
  arrange(desc(Fatalities), .by_group = TRUE) %>%# Sort within each Year group by Fatalities
  slice_max(order_by = Fatalities, n = 1, with_ties = FALSE) # Slice the top 2 rows for each Year

# The resulting sf dataframe will keep the top row for each Year in terms of number of fatalities.


acled_data_2016.south_buffers_2018 = sf::st_filter(acled_2016_joined_sf, union_buffers_south.2018, .predicate = st_within)


acled_data_2017.south_buffers_2018 = sf::st_filter(acled_2017_joined_sf, union_buffers_south.2018, .predicate = st_within)


acled_data_2018.south_buffers_2018 = sf::st_filter(acled_2018_joined_sf, union_buffers_south.2018, .predicate = st_within)


acled_data_2019.south_buffers_2018 = sf::st_filter(acled_2019_joined_sf, union_buffers_south.2018, .predicate = st_within)


acled_data_2020.south_buffers_2018 = sf::st_filter(acled_2020_joined_sf, union_buffers_south.2018, .predicate = st_within)


acled_data_2021.south_buffers_2018 = sf::st_filter(acled_2021_joined_sf, union_buffers_south.2018, .predicate = st_within)


acled_data_all_years.south_buffers_2018 = rbind(acled_data_2016.south_buffers_2018, acled_data_2017.south_buffers_2018, acled_data_2018.south_buffers_2018, acled_data_2019.south_buffers_2018, acled_data_2020.south_buffers_2018, acled_data_2021.south_buffers_2018)


# Filtering, transforming, summarizing, and then retaining top 2 rows for each year based on fatalities
violence_per_identity_militia_actor.south_buffers_2018 <- acled_data_all_years.south_buffers_2018 %>%
  filter(Perpetrator == "Identity Militias", admin1 == "South Darfur") %>%  # Keep only rows where Perpetrator is "Identity Militias" and where admin1 is "South Darfur"
  mutate(Year = year,                      
         Actor = actor1) %>%
  group_by(Year, Actor) %>%                       # Group by Year and Actor
  summarise(
    Fatalities = sum(fatalities, na.rm = TRUE),   # Sum fatalities, removing NA values
    Attacks = sum(attacks, na.rm = TRUE),         # Sum attacks, removing NA values
    .groups = 'drop'                              # Drop the grouping structure afterwards
  ) %>%
  mutate(Buffers = "2018 Closed Base Areas") %>% # Add new column denoting the buffer
  group_by(Year) %>%                             # Regroup by Year only
  arrange(desc(Fatalities), .by_group = TRUE) %>%# Sort within each Year group by Fatalities
  slice_max(order_by = Fatalities, n = 1, with_ties = FALSE) # Slice the top 2 rows for each Year

# The resulting sf dataframe will keep the top row for each Year in terms of number of fatalities.


acled_data_2016.south_buffers_2019 = sf::st_filter(acled_2016_joined_sf, union_buffers_south.2019, .predicate = st_within)


acled_data_2017.south_buffers_2019 = sf::st_filter(acled_2017_joined_sf, union_buffers_south.2019, .predicate = st_within)


acled_data_2018.south_buffers_2019 = sf::st_filter(acled_2018_joined_sf, union_buffers_south.2019, .predicate = st_within)


acled_data_2019.south_buffers_2019 = sf::st_filter(acled_2019_joined_sf, union_buffers_south.2019, .predicate = st_within)


acled_data_2020.south_buffers_2019 = sf::st_filter(acled_2020_joined_sf, union_buffers_south.2019, .predicate = st_within)


acled_data_2021.south_buffers_2019 = sf::st_filter(acled_2021_joined_sf, union_buffers_south.2019, .predicate = st_within)

acled_data_all_years.south_buffers_2019 = rbind(acled_data_2016.south_buffers_2019, acled_data_2017.south_buffers_2019, acled_data_2018.south_buffers_2019, acled_data_2019.south_buffers_2019, acled_data_2020.south_buffers_2019, acled_data_2021.south_buffers_2019)


# Filtering, transforming, summarizing, and then retaining top 2 rows for each year based on fatalities
violence_per_identity_militia_actor.south_buffers_2019 <- acled_data_all_years.south_buffers_2019 %>%
  filter(Perpetrator == "Identity Militias", admin1 == "South Darfur") %>%  # Keep only rows where Perpetrator is "Identity Militias" and where admin1 is "South Darfur"
  mutate(Year = year,                      
         Actor = actor1) %>%
  group_by(Year, Actor) %>%                       # Group by Year and Actor
  summarise(
    Fatalities = sum(fatalities, na.rm = TRUE),   # Sum fatalities, removing NA values
    Attacks = sum(attacks, na.rm = TRUE),         # Sum attacks, removing NA values
    .groups = 'drop'                              # Drop the grouping structure afterwards
  ) %>%
  mutate(Buffers = "2019 Closed Base Areas") %>% # Add new column denoting the buffer
  group_by(Year) %>%                             # Regroup by Year only
  arrange(desc(Fatalities), .by_group = TRUE) %>%# Sort within each Year group by Fatalities
  slice_max(order_by = Fatalities, n = 1, with_ties = FALSE) # Slice the top 2 rows for each Year

# The resulting sf dataframe will keep the top row for each Year in terms of number of fatalities


# CALCULATNG ATTACKS ON CIVILIANS & FATALITIES PER YEAR INSIDE 50 MILE RADIUS BUFFERS AROUND WEST DARFUR BASES CLOSED IN 2017, 2018, and 2019

# length() calculates the number of civilian attacks
# sum() calculates the number of fatalities from these attacks



acled_data_2016.west_buffers_2017 = sf::st_filter(acled_2016_joined_sf, union_buffers_west.2017, .predicate = st_within)


acled_data_2017.west_buffers_2017 = sf::st_filter(acled_2017_joined_sf, union_buffers_west.2017, .predicate = st_within)


acled_data_2018.west_buffers_2017 = sf::st_filter(acled_2018_joined_sf, union_buffers_west.2017, .predicate = st_within)


acled_data_2019.west_buffers_2017 = sf::st_filter(acled_2019_joined_sf, union_buffers_west.2017, .predicate = st_within)


acled_data_2020.west_buffers_2017 = sf::st_filter(acled_2020_joined_sf, union_buffers_west.2017, .predicate = st_within)


acled_data_2021.west_buffers_2017 = sf::st_filter(acled_2021_joined_sf, union_buffers_west.2017, .predicate = st_within)

acled_data_all_years.west_buffers_2017 = rbind(acled_data_2016.west_buffers_2017, acled_data_2017.west_buffers_2017, acled_data_2018.west_buffers_2017, acled_data_2019.west_buffers_2017, acled_data_2020.west_buffers_2017, acled_data_2021.west_buffers_2017)


# Filtering, transforming, summarizing, and then retaining top 2 rows for each year based on fatalities
violence_per_identity_militia_actor.west_buffers_2017 <- acled_data_all_years.west_buffers_2017 %>%
  filter(Perpetrator == "Identity Militias", admin1 == "West Darfur") %>%  # Keep only rows where Perpetrator is "Identity Militias" and where admin1 is "West Darfur"
  mutate(Year = year,                      
         Actor = actor1) %>%
  group_by(Year, Actor) %>%                         # Group by Year and Actor
  summarise(
    Fatalities = sum(fatalities, na.rm = TRUE),     # Sum fatalities, removing NA values
    Attacks = sum(attacks, na.rm = TRUE),           # Sum attacks, removing NA values
    .groups = 'drop'                                # Drop the grouping structure afterwards
  ) %>%
  mutate(Buffers = "2017 Closed Base Areas") %>%    # Add new column denoting the buffer
  group_by(Year) %>%                                # Regroup by Year only
  arrange(desc(Fatalities), .by_group = TRUE) %>%   # Sort within each Year group by Fatalities
  slice_max(order_by = Fatalities, n = 1, with_ties = FALSE)  # Slice the top 2 rows for each Year

# The resulting sf dataframe will keep the top row for each Year in terms of number of fatalities.


acled_data_2016.west_buffers_2018 = sf::st_filter(acled_2016_joined_sf, union_buffers_west.2018, .predicate = st_within)


acled_data_2017.west_buffers_2018 = sf::st_filter(acled_2017_joined_sf, union_buffers_west.2018, .predicate = st_within)


acled_data_2018.west_buffers_2018 = sf::st_filter(acled_2018_joined_sf, union_buffers_west.2018, .predicate = st_within)


acled_data_2019.west_buffers_2018 = sf::st_filter(acled_2019_joined_sf, union_buffers_west.2018, .predicate = st_within)


acled_data_2020.west_buffers_2018 = sf::st_filter(acled_2020_joined_sf, union_buffers_west.2018, .predicate = st_within)


acled_data_2021.west_buffers_2018 = sf::st_filter(acled_2021_joined_sf, union_buffers_west.2018, .predicate = st_within)

acled_data_all_years.west_buffers_2018 = rbind(acled_data_2016.west_buffers_2018, acled_data_2017.west_buffers_2018, acled_data_2018.west_buffers_2018, acled_data_2019.west_buffers_2018, acled_data_2020.west_buffers_2018, acled_data_2021.west_buffers_2018)


# Filtering, transforming, summarizing, and then retaining top 2 rows for each year based on fatalities
violence_per_identity_militia_actor.west_buffers_2018 <- acled_data_all_years.west_buffers_2018 %>%
  filter(Perpetrator == "Identity Militias", admin1 == "West Darfur") %>%  # Keep only rows where Perpetrator is "Identity Militias" and where admin1 is "West Darfur"
  mutate(Year = year,                      
         Actor = actor1) %>%
  group_by(Year, Actor) %>%                       # Group by Year and Actor
  summarise(
    Fatalities = sum(fatalities, na.rm = TRUE),   # Sum fatalities, removing NA values
    Attacks = sum(attacks, na.rm = TRUE),         # Sum attacks, removing NA values
    .groups = 'drop'                              # Drop the grouping structure afterwards
  ) %>%
  mutate(Buffers = "2018 Closed Base Areas") %>% # Add new column denoting the buffer
  group_by(Year) %>%                             # Regroup by Year only
  arrange(desc(Fatalities), .by_group = TRUE) %>%# Sort within each Year group by Fatalities
  slice_max(order_by = Fatalities, n = 1, with_ties = FALSE) # Slice the top 2 rows for each Year

# The resulting sf dataframe will keep the top row for each Year in terms of number of fatalities.


acled_data_2016.west_buffers_2019 = sf::st_filter(acled_2016_joined_sf, union_buffers_west.2019, .predicate = st_within)


acled_data_2017.west_buffers_2019 = sf::st_filter(acled_2017_joined_sf, union_buffers_west.2019, .predicate = st_within)


acled_data_2018.west_buffers_2019 = sf::st_filter(acled_2018_joined_sf, union_buffers_west.2019, .predicate = st_within)


acled_data_2019.west_buffers_2019 = sf::st_filter(acled_2019_joined_sf, union_buffers_west.2019, .predicate = st_within)


acled_data_2020.west_buffers_2019 = sf::st_filter(acled_2020_joined_sf, union_buffers_west.2019, .predicate = st_within)


acled_data_2021.west_buffers_2019 = sf::st_filter(acled_2021_joined_sf, union_buffers_west.2019, .predicate = st_within)


acled_data_all_years.west_buffers_2019 = rbind(acled_data_2016.west_buffers_2019, acled_data_2017.west_buffers_2019, acled_data_2018.west_buffers_2019, acled_data_2019.west_buffers_2019, acled_data_2020.west_buffers_2019, acled_data_2021.west_buffers_2019)



violence_per_identity_militia_actor.west_buffers_2019 <- acled_data_all_years.west_buffers_2019 %>%
  filter(Perpetrator == "Identity Militias", admin1 == "West Darfur") %>%  # Keep only rows where Perpetrator is "Identity Militias" and where admin1 is "West Darfur"
  mutate(Year = year,                      
         Actor = actor1) %>%
  group_by(Year, Actor) %>%                       # Group by Year and Actor
  summarise(
    Fatalities = sum(fatalities, na.rm = TRUE),   # Sum fatalities, removing NA values
    Attacks = sum(attacks, na.rm = TRUE),         # Sum attacks, removing NA values
    .groups = 'drop'                              # Drop the grouping structure afterwards
  ) %>%
  mutate(Buffers = "2019 Closed Base Areas") %>% # Add new column denoting the buffer
  group_by(Year) %>%                             # Regroup by Year only
  arrange(desc(Fatalities), .by_group = TRUE) %>%# Sort within each Year group by Fatalities
  slice_max(order_by = Fatalities, n = 1, with_ties = FALSE)        # Slice the top 2 rows for each Year


# The resulting sf dataframe will keep the top row for each Year in terms of number of fatalities.


# Combine all of the resulting sf objects from above, for South Darfur buffers

violence_per_identity_militia_actor.south_buffers <- rbind(violence_per_identity_militia_actor.south_buffers_2017, violence_per_identity_militia_actor.south_buffers_2018, violence_per_identity_militia_actor.south_buffers_2019) %>%
  group_by(Year) %>%                             # Regroup by Year only
  arrange(desc(Fatalities), .by_group = TRUE) %>%# Sort within each Year group by Fatalities
  slice_max(order_by = Fatalities, n = 1, with_ties = FALSE)  %>%
  rename(Areas = Buffers) %>%                     # Rename 'Buffer' as 'Area'
  as.data.frame() %>%                             # Remove 'geometry' column by converting the sf object to a dataframe
  select(-geometry)


# Combine all of the resulting sf objects from above, for West Darfur buffers

violence_per_identity_militia_actor.west_buffers <- rbind(violence_per_identity_militia_actor.west_buffers_2017, violence_per_identity_militia_actor.west_buffers_2018, violence_per_identity_militia_actor.west_buffers_2019) %>%
  group_by(Year) %>%                             # Regroup by Year only
  arrange(desc(Fatalities), .by_group = TRUE) %>%# Sort within each Year group by Fatalities
  slice_max(order_by = Fatalities, n = 1, with_ties = FALSE)  %>%
  rename(Areas = Buffers) %>%                      # Rename 'Buffer' as 'Area'
  as.data.frame() %>%
  select(-geometry) # Remove 'geometry' column by converting the sf object to a dataframe

combined <- rbind(violence_per_identity_militia_actor.south_buffers, violence_per_identity_militia_actor.west_buffers)


Because of the substantial spikes observed in identity militia civilian killings since 2020 in South Darfur and since 2019 in West Darfur, the next two tables examine such killings from both regions. To maintain brevity, the focus of each chart is only on the most lethal identity militia each year within any of the buffers around withdrawn UN bases.


In South Darfur, the first table shows low killings from 2017 to 2019, but a surge in 2020. Of the 73 identity militia killings in all of South Darfur in 2020, 40 (55%) were committed by “Darfur communal militias” within 50 mi of the UN bases closed in 2018. In 2021, of the 38 killings, 14 (37%) were committed by Darfur communal militias near these same bases.


Unfortunately, ACLED does not further disaggregate the “Darfur Communal Militia (Sudan)” category, which would otherwise clarify which specific groups within this militia category were responsible for these killings.


library(scales)
library(kableExtra)

# For the following tables, I want to highlight the most important fatality values considering the fatality figures from both the violence_per_identity_militia_actor.south_buffers & violence_per_identity_militia_actor.west_buffers dataframes at the same time. This will help the reader put in context the fatalities shown in any one of the tables with respect to the overall fatality figures from both tables. E.g., we know South Darfur had fewer civilian killings than West Darfur between 2016-2021 in areas within 50 mi of where the UN would eventually withdraw their bases, and I want readers to more easily keep this in mind while viewing both tables.

# Get min, max, and 3rd quantile values for the "Fatalities" column of the combined sf dataframe for scaling
min_val <- min(combined$Fatalities)
max_val <- max(combined$Fatalities)
quantile_val <- quantile(unlist(combined$Fatalities), 0.75) # calculate the 3rd quantile

# Scale the fatality figures from the South Darfur dataframe
violence_per_identity_militia_actor.south_buffers$Fatalities <- lapply(violence_per_identity_militia_actor.south_buffers$Fatalities, 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
  }
})


# This code block will center neither the column names nor the column contents. Since the contents of the column "Attacks" is right aligned (being integers) and since the contents of the column "Areas" is left aligned (being strings), it makes reading the table somewhat difficult.

# library(kableExtra)
# 
# violence_per_identity_militia_actor.south_buffers %>%
#   kbl(caption = "<b>Identity Militias which Killed the Most Civilians near closed UN Bases in South Darfur</b>") %>%
#   kable_classic(full_width = F, html_font = "Cambria") %>%
#   kable_styling(bootstrap_options = c("striped", "hover", "condensed", "responsive"))


# This code block will center both the column names as well as the contents of each column. However, by centering the contents of the column "Actor", it makes the table look somewhat messy since the strings in the rows of the column are not the same length

# library(kableExtra)
# 
# violence_per_identity_militia_actor.south_buffers %>%
#   kbl(caption = "<b>Identity Militias which Killed the Most Civilians near closed UN Bases in South Darfur</b>", 
#       escape = FALSE, align = c("c", "c", "c", "c", "c")) %>%
#   kable_classic(full_width = F, html_font = "Cambria") %>%
#   kable_styling(bootstrap_options = c("striped", "hover", "condensed", "responsive"))



# This code block will center the column names without centering the contents of each column

# library(kableExtra)
# 
# # Generate the table and convert to HTML
# kable_html <- violence_per_identity_militia_actor.south_buffers %>%
#   kbl(caption = "<b>Identity Militias which Killed the Most Civilians near Closed UN Bases in South Darfur</b>", escape = FALSE) %>%
#   kable_classic(full_width = F, html_font = "Cambria") %>%
#   kable_styling(bootstrap_options = c("striped", "hover", "condensed", "responsive"))
# 
# # Add custom CSS to center the column headers
# kable_html <- kable_html %>%
#   row_spec(0, extra_css = "text-align: center;")
# 
# # To print the HTML table in RMarkdown or R console
# kable_html

#This code centers the column names of every column and also centers the column contents of "Fatalities" and "Attacks" in order to make these columns' contents more legible than is the case when these columns' contents are not centered.

violence_per_identity_militia_actor.south_buffers %>%
  kbl(caption = "<b>Identity Militias which Killed the Most Civilians near Closed UN Bases in South Darfur</b>", 
      escape = FALSE) %>%
  kable_classic(full_width = F, html_font = "Cambria") %>%
  kable_styling(bootstrap_options = c("striped", "hover", "condensed", "responsive")) %>%
  row_spec(0, extra_css = "text-align: center;") %>%
  column_spec(3, extra_css = "text-align: center;") %>%
  column_spec(4, extra_css = "text-align: center;")
Identity Militias which Killed the Most Civilians near Closed UN Bases in South Darfur
Year Actor Fatalities Attacks Areas
2016 Unidentified Communal Militia (Sudan) 22 9 2017 Closed Base Areas
2017 Abala Ethnic Militia (Sudan) 6 1 2019 Closed Base Areas
2018 Unidentified Communal Militia (Sudan) 7 8 2017 Closed Base Areas
2019 Darfur Communal Militia (Sudan) 6 6 2017 Closed Base Areas
2020 Darfur Communal Militia (Sudan) 40 7 2018 Closed Base Areas
2021 Darfur Communal Militia (Sudan) 14 12 2018 Closed Base Areas


The table for West Darfur below reveals more about the specific identity militias involved in civilian killings than does the table for South Darfur. In 2021, 144 civilian killings by identity militias occurred in all of West Darfur, with 99 (69%) by Rizeigat Arab militias within 50 mi of the 2018-closed UN bases. In 2019, of the 39 civilian killings by identity militias in all of West Darfur, 37 (95%) were by Maaliya Arab militias, also within 50 mi of these same closed bases.


# Scale the fatality figures from the West Darfur dataframe

violence_per_identity_militia_actor.west_buffers$Fatalities <- lapply(violence_per_identity_militia_actor.west_buffers$Fatalities, 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
  }
})


#This code centers the column names of every column and also centers the column contents of "Fatalities" and "Attacks" in order to make these columns' contents more legible than is the case when these columns' contents are not centered.

violence_per_identity_militia_actor.west_buffers %>%
  kbl(caption = "<b>Identity Militias which Killed the Most Civilians near Closed UN Bases in West Darfur</b>", 
      escape = FALSE) %>%
  kable_classic(full_width = F, html_font = "Cambria") %>%
  kable_styling(bootstrap_options = c("striped", "hover", "condensed", "responsive")) %>%
  row_spec(0, extra_css = "text-align: center;") %>%
  column_spec(3, extra_css = "text-align: center;") %>%
  column_spec(4, extra_css = "text-align: center;")
Identity Militias which Killed the Most Civilians near Closed UN Bases in West Darfur
Year Actor Fatalities Attacks Areas
2016 Abala Ethnic Militia (Sudan) 9 1 2018 Closed Base Areas
2017 Unidentified Communal Militia (Chad) 1 1 2017 Closed Base Areas
2018 Zaghawa Ethnic Militia (Chad) 9 1 2018 Closed Base Areas
2019 Maaliya Ethnic Militia (Sudan) 37 7 2018 Closed Base Areas
2020 Darfur Communal Militia (Sudan) 5 6 2018 Closed Base Areas
2021 Rizeigat Ethnic Militia (Sudan) 99 13 2018 Closed Base Areas


In the next 2 tables, I will examine all civilian killings committed by all identity militias in the years and inside the buffers found to be especially deadly in the prior 2 tables: South Darfur in 2020 and 2021 within 50 mi of the UN bases withdrawn from South Darfur in 2018, and West Darfur in 2019 and 2021 within 50 mi of the UN bases withdrawn from West Darfur in 2018.


# Create a map sf object of South Darfur
south_darfur <- darfur_internal_sf %>% 
  filter(ADM1_EN == "South Darfur")

# Calculate the area of South Darfur
south_darfur_area <- south_darfur %>%
  st_area() %>%
  sum() # Summing in case of multiple geometries

# Calculate the area of the part of the buffer that is actually inside of South Darfur
area_of_part_of_union_buffers_south.2018_inside_south_darfur <- st_intersection(union_buffers_south.2018, south_darfur) %>%
  st_area() %>%
  sum() # Summing in case of multiple geometries


# Calculate percentage and print
percentage_area_south_darfur_2018_buffers <- area_of_part_of_union_buffers_south.2018_inside_south_darfur / south_darfur_area

# Round the result to one decimal place
rounded_percentage <- round(percentage_area_south_darfur_2018_buffers * 100, 2)

# Print the result with one decimal place
print(paste("The area of the 2018 South Darfur 50 mi radius buffer makes up", rounded_percentage, "percent of the area of all of South Darfur"))
## [1] "The area of the 2018 South Darfur 50 mi radius buffer makes up 25.94 percent of the area of all of South Darfur"
# Create a map sf object of West Darfur
west_darfur <- darfur_internal_sf %>% 
  filter(ADM1_EN == "West Darfur")

# Calculate the area of the part of the buffer that is actually inside of West Darfur
area_of_part_of_union_buffers_west.2018_inside_west_darfur <- st_intersection(union_buffers_west.2018, west_darfur) %>%
  st_area() %>%
  sum() # Summing in case of multiple geometries

# Calculate the area of West Darfur
west_darfur_area <- west_darfur %>%
  st_area() %>%
  sum() # Summing in case of multiple geometries

# Calculate percentage and print
percentage_area_west_darfur_2018_buffers <- area_of_part_of_union_buffers_west.2018_inside_west_darfur / west_darfur_area

# Round the result to one decimal place
rounded_percentage <- round(percentage_area_west_darfur_2018_buffers * 100, 2)

# Print the result with one decimal place
print(paste("The area of the 2018 West Darfur 50 mi radius buffer makes up", rounded_percentage, "percent of the area of all of West Darfur"))
## [1] "The area of the 2018 West Darfur 50 mi radius buffer makes up 58.47 percent of the area of all of West Darfur"


The area within the buffer around the 2 2018-withdrawn UN bases comprises 26% of South Darfur’s total area (per my calculations). Using this as a benchmark, I will next see whether all identity militia killings falling within the buffer as percentage of all identity militia killings within all of South Darfur, in 2019 and in 2021, are each greater than 26%. If they are, this provides supporting evidence that identity militia killings in the areas near the withdrawn UN bases were disproportionately high in the areas where UN troops likely would have been able to respond to violence or prevent violence had the bases not been withdrawn.


Afterwards, we will turn to West Darfur, taking the same approach as with South Darfur in establishing a benchmark. The area within the buffer around the 2 2018-withdrawn UN bases comprises 58% of West Darfur’s total area (according to my calculations). We will thus see whether all identity militia killings falling within the buffer as a percentage of all identity militia killings within all of West Darfur, in 2019 and in 2021, are each greater than 58%.


violence_per_identity_militia_actor.south_buffers_2018 <- acled_data_all_years.south_buffers_2018 %>%
  filter(Perpetrator == "Identity Militias", fatalities > 0, year == 2020 | year == 2021, admin1 == "South Darfur") %>%  # Keep only rows where Perpetrator is "Identity Militias", where admin1 is "South Darfur", and where there was at least 1 fatality from the attack, and where year = 2020
  mutate(Year = year,                      
         Actor = actor1) %>%
  group_by(Year, Actor) %>%                       # Group by Year and Actor
  summarise(
    Fatalities = sum(fatalities, na.rm = TRUE),   # Sum fatalities, removing NA values
    Attacks = sum(attacks, na.rm = TRUE),         # Sum attacks, removing NA values
    .groups = 'drop'                              # Drop the grouping structure afterwards
  ) %>%
  mutate(Areas = "2018 Closed Base Areas"         # Add new column denoting the 2018 buffer
  ) %>%                     
  group_by(Year) %>%                              # Regroup by Year only
  arrange(desc(Fatalities), .by_group = TRUE) %>% # Sort within each Year group by Fatalities
  #slice_max(order_by = Fatalities, n = 1, with_ties = FALSE) # Slice the top 2 rows for each Year
  as.data.frame() %>%                             # Convert the sf object to a dataframe
  select(-geometry)                     # Delete the geometry column


# Convert Attacks and Areas to character in the main data frame
violence_per_identity_militia_actor.south_buffers_2018 <- violence_per_identity_militia_actor.south_buffers_2018 %>%
  mutate(Attacks = as.character(Attacks),
         Areas = as.character(Areas))

# Calculate the sum of fatalities for each year and create a summary row with empty strings
summary_fatalities <- violence_per_identity_militia_actor.south_buffers_2018 %>%
  group_by(Year) %>%
  summarise(Fatalities = sum(Fatalities), .groups = 'drop') %>%
  mutate(Actor = "Total", Attacks = "", Areas = "")

# Append the summary row to the original data frame
combined_data <- violence_per_identity_militia_actor.south_buffers_2018 %>%
  bind_rows(summary_fatalities) %>%
  arrange(Year, is.na(Actor))  # Arrange by Year and place the summary row at the end of each year's data

# Find row numbers for "Total" summary rows
bold_rows <- which(combined_data$Actor == "Total")

# Version of table that does not center the caption
# Generate the table with the kableExtra package
# table_output <- combined_data %>%
#   kbl(caption = "<b>Civilian Killings by Identity Militia in South Darfur (2020) within 50 Mi of UN Bases Closed in 2018</b>",
#       escape = FALSE) %>%
#   kable_classic(full_width = F, html_font = "Cambria") %>%
#   kable_styling(bootstrap_options = c("striped", "hover", "condensed", "responsive")) %>%
#   row_spec(0, extra_css = "text-align: center;") %>%
#   column_spec(3, extra_css = "text-align: center;") %>%
#   column_spec(4, extra_css = "text-align: center;") %>%
#   row_spec(bold_rows, bold = TRUE)  # Bold the summary rows
# table_output

# Version of table that centers the caption
table_output <- combined_data %>%
  kbl(caption = "<div style='text-align: center;'><b>Civilian Killings by Identity Militias in South Darfur (2020 and 2021) within 50 Mi of UN Bases Closed in 2018</b></div>",
      escape = FALSE) %>%
  kable_classic(full_width = F, html_font = "Cambria") %>%
  kable_styling(bootstrap_options = c("striped", "hover", "condensed", "responsive")) %>%
  row_spec(0, extra_css = "text-align: center;") %>%
  column_spec(3, extra_css = "text-align: center;") %>%
  column_spec(4, extra_css = "text-align: center;") %>%
  row_spec(bold_rows, bold = TRUE)  # Bold the summary rows
table_output
Civilian Killings by Identity Militias in South Darfur (2020 and 2021) within 50 Mi of UN Bases Closed in 2018
Year Actor Fatalities Attacks Areas
2020 Darfur Communal Militia (Sudan) 40 6 2018 Closed Base Areas
2020 Fulani Ethnic Militia (Sudan) 28 4 2018 Closed Base Areas
2020 Al-Falata Ethnic Militia (Sudan) 3 1 2018 Closed Base Areas
2020 Total 71
2021 Darfur Communal Militia (Sudan) 14 9 2018 Closed Base Areas
2021 Fulani Ethnic Militia (Sudan) 9 4 2018 Closed Base Areas
2021 Rizeigat Ethnic Militia (Sudan) 2 1 2018 Closed Base Areas
2021 Masalit Ethnic Militia (Sudan) 1 1 2018 Closed Base Areas
2021 Total 26


We can see from the above table that 71 killings (or 97%) of the 73 that occurred in all of South Darfur in 2020 occurred within 50 mi of the bases withdrawn in 2018, as did 26 (or 68%) of the 38 killings in 2021. In both years, these percentages far exceeded the 26% benchmark.


violence_per_identity_militia_actor.west_buffers_2018 <- acled_data_all_years.west_buffers_2018 %>%
  filter(Perpetrator == "Identity Militias", fatalities > 0, year == 2019 | year == 2021, admin1 == "West Darfur") %>%  # Keep only rows where Perpetrator is "Identity Militias", where admin1 is "West Darfur" and where there was at least 1 fatality from the attack, and where year = 2019 or 2021
  mutate(Year = year,                      
         Actor = actor1) %>%
  group_by(Year, Actor) %>%                       # Group by Year and Actor
  summarise(
    Fatalities = sum(fatalities, na.rm = TRUE),   # Sum fatalities, removing NA values
    Attacks = sum(attacks, na.rm = TRUE),         # Sum attacks, removing NA values
    .groups = 'drop'                              # Drop the grouping structure afterwards
  ) %>%
  mutate(Buffers = "2018 Closed Base Areas",
         Areas = Buffers) %>%  # Add new column denoting the 2018 buffer
  group_by(Year) %>%                              # Regroup by Year only
  arrange(desc(Fatalities), .by_group = TRUE) %>% # Sort within each Year group by Fatalities
  #slice_max(order_by = Fatalities, n = 1, with_ties = FALSE) # Slice the top 2 rows for each Year
  as.data.frame() %>%                             # Convert the sf object to a dataframe
  select(-geometry, -Buffers)

# Convert Attacks and Areas to character in the main data frame
violence_per_identity_militia_actor.west_buffers_2018 <- violence_per_identity_militia_actor.west_buffers_2018 %>%
  mutate(Attacks = as.character(Attacks),
         Areas = as.character(Areas))

# Calculate the sum of fatalities for each year and create a summary row with empty strings
summary_fatalities <- violence_per_identity_militia_actor.west_buffers_2018 %>%
  group_by(Year) %>%
  summarise(Fatalities = sum(Fatalities), .groups = 'drop') %>%
  mutate(Actor = "Total", Attacks = "", Areas = "")

# Append the summary row to the original data frame
combined_data <- violence_per_identity_militia_actor.west_buffers_2018 %>%
  bind_rows(summary_fatalities) %>%
  arrange(Year, is.na(Actor))  # Arrange by Year and place the summary row at the end of each year's data

# Find row numbers for "Total" summary rows
bold_rows <- which(combined_data$Actor == "Total")

# Version of table that does not center the caption
# Generate the table with the kableExtra package
# table_output <- violence_per_identity_militia_actor.west_buffers_2018 %>%
#   kbl(caption = "<b>2019 & 2020 Civilian Killings by Identity Militias near Closed UN Bases-West Darfur</b>",
#       escape = FALSE) %>%
#   kable_classic(full_width = F, html_font = "Cambria") %>%
#   kable_styling(bootstrap_options = c("striped", "hover", "condensed", "responsive")) %>%
#   row_spec(0, extra_css = "text-align: center;") %>%
#   column_spec(3, extra_css = "text-align: center;") %>%
#   column_spec(4, extra_css = "text-align: center;") %>%
#   row_spec(bold_rows, bold = TRUE)  # Bold the summary rows
# table_output

# Version of table that centers the caption
table_output <- combined_data %>%
  kbl(caption = "<div style='text-align: center;'><b>Civilian Killings by Identity Militias in West Darfur (2019 & 2021) within 50 Mi of UN Bases Closed in 2018</b></div>",
      escape = FALSE) %>%
  kable_classic(full_width = F, html_font = "Cambria") %>%
  kable_styling(bootstrap_options = c("striped", "hover", "condensed", "responsive")) %>%
  row_spec(0, extra_css = "text-align: center;") %>%
  column_spec(3, extra_css = "text-align: center;") %>%
  column_spec(4, extra_css = "text-align: center;") %>%
  row_spec(bold_rows, bold = TRUE)  # Bold the summary rows
table_output
Civilian Killings by Identity Militias in West Darfur (2019 & 2021) within 50 Mi of UN Bases Closed in 2018
Year Actor Fatalities Attacks Areas
2019 Maaliya Ethnic Militia (Sudan) 37 7 2018 Closed Base Areas
2019 Darfur Communal Militia (Sudan) 2 2 2018 Closed Base Areas
2019 Total 39
2021 Rizeigat Ethnic Militia (Sudan) 99 5 2018 Closed Base Areas
2021 Darfur Communal Militia (Sudan) 13 7 2018 Closed Base Areas
2021 Masalit Ethnic Militia (Sudan) 2 1 2018 Closed Base Areas
2021 Total 114


From the above chart, we can see that 39 civilian killings were committed by identity militias in 2019 within 50 mi of the UN bases withdrawn from West Darfur in 2018. This constitutes 100% of all civilian killings committed by identity militias in all of West Darfur in 2019.


We also see that 114 (or 79%) of the 144 civilian killings by identity militias in all of West Darfur in 2021 occurred within 50 mi of the UN bases withdrawn in 2018. Thus, in both 2019 and 2021, the benchmark was far surpassed.


We can see from these charts as well as from prior visuals that the evidence supports the theory that one of the factors which played a role in sharp increases in violence against civilians in Darfur was the withdrawal of UN bases as UNAMID closed. Additionally, we have seen there were opportunities when the UN could have recognized rising levels of violence following base withdrawals and slowed the pace of closing the remaining bases in Darfur, but instead chose not to.


# 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)

# I removed the code for "Next Page" both from the R code above and from the html code below because this is the last page