This R notebook compares Cities and Armed Conflicts Events (CACE) Conflicts and Death markers. The study region is all countries in the African continent, including Madagascar.

The following graphics evaluate conflicts deaths by type of UCDP organized violence.

  1. State-based conflict - A state is either an internationally recognized sovereign government controlling a specified territory, or an internationally unrecognized government controlling a specified territory whose sovereignty is not disputed by another internationally recognized sovereign government previously controlling the same territory. 
  2. Non-state conflict - The use of armed force between two organised armed groups, neither of which is the government of a state, which results in at least 25 battle-related deaths in a year.
  3. One-sided violence - The deliberate use of armed force by the government of a state or by a formally organised group against civilians which results in at least 25 deaths in a year.

Full definitions for Type of Violence can be found at https://www.pcr.uu.se/research/ucdp/definitions.


library(tidyverse)
## ── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
## ✔ dplyr     1.1.4     ✔ readr     2.1.6
## ✔ forcats   1.0.1     ✔ stringr   1.6.0
## ✔ ggplot2   4.0.1     ✔ tibble    3.3.0
## ✔ lubridate 1.9.4     ✔ tidyr     1.3.2
## ✔ purrr     1.2.0     
## ── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
## ✖ dplyr::filter() masks stats::filter()
## ✖ dplyr::lag()    masks stats::lag()
## ℹ Use the conflicted package (<http://conflicted.r-lib.org/>) to force all conflicts to become errors
library(ggplot2)
library(biscale)
## Warning: package 'biscale' was built under R version 4.5.3
library(cowplot)
## Warning: package 'cowplot' was built under R version 4.5.3
## 
## Attaching package: 'cowplot'
## 
## The following object is masked from 'package:lubridate':
## 
##     stamp
library(scales)
## 
## Attaching package: 'scales'
## 
## The following object is masked from 'package:purrr':
## 
##     discard
## 
## The following object is masked from 'package:readr':
## 
##     col_factor
library(rjson)
library(sf)
## Linking to GEOS 3.13.1, GDAL 3.11.4, PROJ 9.7.0; sf_use_s2() is TRUE
library(geojsonsf)
world.data <- fromJSON(file = "world-data.geojson")
features <- world.data[['features']]

continent <- sapply(features, function(x) x$properties[['continent']])

geo <- sapply(features, function(x) x$properties[['iso_a3']]) %>% 
  str_to_lower()
continents <- as.data.frame(cbind(geo, continent))

continent.countries <- continents[continents$continent == "Africa", c("geo")]

countries.json <- fromJSON(file = "countries.geojson")

countries <- geojson_sf(toJSON(countries.json))
countries$geo <- str_to_lower(countries$iso_a3)
countries <- subset(countries, geo %in% continent.countries)
conflict.data <- read.csv(file = "cace_conflicts.csv") %>%
  st_as_sf(., wkt = "geom_wkt", crs = 4326) %>%
  st_join(., countries, left = FALSE)

conflict.data$violence_type <- 
  with(conflict.data, ifelse(type_of_violence == 1, "1. State-based",
                        ifelse(type_of_violence == 2, "2. Non-state", 
                               "3. One-sided")))
subset(
    conflict.data, 
    select = c("id", "year", "geo", "country_name", "city_name", "violence_type")
  ) %>%
  head()
## Simple feature collection with 6 features and 6 fields
## Geometry type: POINT
## Dimension:     XY
## Bounding box:  xmin: -1.72753 ymin: 34.84969 xmax: 3.666667 ymax: 36.75
## Geodetic CRS:  WGS 84
##       id year geo country_name city_name  violence_type
## 604 1489 1998 dza      Algeria           1. State-based
## 605 1490 1996 dza      Algeria           1. State-based
## 606 1491 2000 dza      Algeria           1. State-based
## 607 1492 1994 dza      Algeria           1. State-based
## 608 1493 1997 dza      Algeria           1. State-based
## 609 1496 1995 dza      Algeria           1. State-based
##                      geom_wkt
## 604 POINT (-1.72753 34.84969)
## 605     POINT (-0.5 35.66667)
## 606 POINT (0.166667 35.41667)
## 607        POINT (3 36.08333)
## 608        POINT (3 36.08333)
## 609    POINT (3.666667 36.75)
colnames(conflict.data)
##  [1] "id"                "active_year"       "type_of_violence" 
##  [4] "conflict_new_id"   "conflict_name"     "dyad_new_id"      
##  [7] "dyad_name"         "side_a_new_id"     "gwnoa"            
## [10] "side_a"            "side_b_new_id"     "gwnob"            
## [13] "side_b"            "where_prec"        "where_coordinates"
## [16] "city"              "city_name"         "capital"          
## [19] "major_city"        "top3_cities"       "comment"          
## [22] "adm_1"             "adm_2"             "latitude"         
## [25] "longitude"         "priogrid_gid"      "country_name"     
## [28] "country_id"        "region"            "event_clarity"    
## [31] "date_prec"         "year"              "date_start"       
## [34] "date_end"          "deaths_a"          "deaths_b"         
## [37] "deaths_civilians"  "deaths_unknown"    "best"             
## [40] "low"               "high"              "name"             
## [43] "iso_a3"            "geo"               "geom_wkt"         
## [46] "violence_type"
# Create map of Type of Violence markers

ggplot() +
  geom_sf(
    data = countries,
    fill = "lightgray"
  ) +
  geom_sf(
    data = conflict.data,
    mapping = aes(col = as.factor(violence_type)),
    size = 0.75
  ) +
  labs(
    title = "CACE Type of Violence",
    col = "Type"
  ) +
  theme_bw() +
  theme(
    plot.title = element_text(hjust = 0.5)
  )

sum.data <- conflict.data %>%
  group_by(
    geo
  ) %>%
  summarise(
    iso_a3 = toupper(first(geo)),
    Conflicts = n(),
    Deaths = sum(deaths_a) + sum(deaths_b)
  ) %>%
  as.data.frame(
    .
  ) %>%
  subset(
    ., 
    select = c("iso_a3", "Conflicts", "Deaths")
  )

head(sum.data, 5)
##   iso_a3 Conflicts Deaths
## 1    AGO      1945   9022
## 2    BDI      1453   5959
## 3    BFA        21      5
## 4    CAF      1208    875
## 5    CIV       293    506
ggplot(
  data = sum.data
) +
  geom_point(
    mapping = aes(x = Conflicts, y = Deaths),
    col = "royalblue"
  ) +
  labs(
    title = "CACE Conflicts vs Deaths per Country"
  ) +
  scale_x_continuous(
    labels = number_format(big.mark = ",")
  ) +
  scale_y_continuous(
    labels = number_format(big.mark = ",")
  ) +
  theme_bw() +
  theme(
    plot.title = element_text(hjust = 0.5)
  )

Create a bi-variate map comparing conflicts and deaths by country boundary.

map.data <- bi_class(
  sum.data,
  x = Conflicts, y = Deaths, 
  style = "quantile", dim = 3
) %>%
  merge(
    countries, ., 
    by.x = "iso_a3", by.y = "iso_a3", 
    all.x = TRUE
  )

head(map.data)
## Simple feature collection with 6 features and 6 fields
## Geometry type: GEOMETRY
## Dimension:     XY
## Bounding box:  xmin: -5.470565 ymin: -26.82854 xmax: 30.75226 ymax: 15.11616
## Geodetic CRS:  WGS 84
##   iso_a3                     name geo Conflicts Deaths bi_class
## 1    AGO                   Angola ago      1945   9022      3-3
## 2    BDI                  Burundi bdi      1453   5959      3-3
## 3    BEN                    Benin ben        NA     NA     <NA>
## 4    BFA             Burkina Faso bfa        21      5      1-1
## 5    BWA                 Botswana bwa        NA     NA     <NA>
## 6    CAF Central African Republic caf      1208    875      3-2
##                         geometry
## 1 MULTIPOLYGON (((16.32653 -5...
## 2 POLYGON ((29.34 -4.499983, ...
## 3 POLYGON ((2.691702 6.258817...
## 4 POLYGON ((-2.827496 9.64246...
## 5 POLYGON ((25.64916 -18.5360...
## 6 POLYGON ((15.27946 7.421925...
# Create the map
map <- ggplot() +
  geom_sf(
    data = map.data, 
    mapping = aes(fill = bi_class), 
    color = "black", 
    size = 0.1, 
    show.legend = FALSE
  ) +
  bi_scale_fill(
    pal = "DkBlue",
    dim = 3
  ) +
  labs(
    title = "CACE Conflicts and Deaths",
    subtitle = "Comparision by Country"
  ) +
  theme_bw() +
  theme(
    plot.title = element_text(hjust = 0.5),
    plot.subtitle = element_text(hjust = 0.5)
  )

# Create the legend
legend <- bi_legend(
  pal = "DkBlue", 
  dim = 3, 
  xlab = "Conflicts", 
  ylab = "Deaths", 
  size = 8
)

# Combine map with legend
ggdraw() +
  draw_plot(map, 0, 0, 1, 1) +
  draw_plot(legend, 0.0, 0.2, 0.2, 0.2)