In this short post, we will show how to use the rhdx, dplyr, purrr, sf and gganimate R packages to show the number of fatal incidents in 5 Sahelian countries. The rhdx package is not yet on CRAN, so you will need to use the remotes package to install it first:

remotes::install_gitlab("dickoa/rhdx") ## github mirror also avalailable

gganimate depends on the gifski R package and to install it, make sure you first have the gifski Rust cargo crate installed on your system.

install.packages("gifski")

This analysis was inspired by this tweet by José Luengo-Cabrera, researcher at the Crisis Group.

Our visualization will be done for the following countries in the Sahel : Burkina Faso, Mali, Chad, Mauritania and Niger. There is a lot of insecurity and conflicts in these countries that resulted in the death of several thousands of people.

The goal of this post is to visualize the number of fatal events in theses countries between 2012 and 2018 using an animated map. In order to do that, will need to get the administrative boundaries for these countries. We can get the latest boundaries validated by the governments and the humanitarian community directly from HDX using the rhdx package. We will use rhdx::pull_dataset function and use the name of the dataset of interest as value. rhdx::get_resource and rhdx::download_resource allow to respectively get the a resource by its index and read the data into memory.

set_rhdx_config()

wca <- pull_dataset("west-and-central-africa-administrative-boundaries-levels") %>%
  get_resource(1) %>%
  read_resource()
#> reading layer: wca_adm0
glimpse(wca)
#> Rows: 24
#> Columns: 6
#> $ OBJECTID   <dbl> 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, …
#> $ admin0Name <chr> "Benin", "Burkina Faso", "Cabo Verde", "Cam…
#> $ admin0Pcod <chr> "BJ", "BF", "CV", "CM", "CF", "TD", "CI", "…
#> $ Shape_Leng <dbl> 19.006363, 31.466913, 13.599357, 47.469736,…
#> $ Shape_Area <dbl> 9.52157812, 22.72097221, 0.34276153, 38.086…
#> $ geometry   <MULTIPOLYGON [°]> MULTIPOLYGON (((2.886863 12...…

wca is a Simple Feature and we can manipulate it using sf and dplyr. The data downloaded from HDX covers the 24 countries of West and Central Africa, we will filter the data to extract the 5 countries of interest.

g5_ab <- wca %>%
  filter(admin0Pcod %in% c("BF", "ML", "NE", "MR", "TD"))

We can now check our data by plotting it

g5_ab %>%
  ggplot() +
  geom_sf() +
  theme_minimal()

Now that we have our background map, the next step is to get the conflict data. One of the main source for conflict data in the Sahel is ACLED and it can also be accessed from HDX. We will use the rhdx::search_datasets function since it allows to access multiple datasets as list. HDX is based on CKAN whose search is powered by SOLR. SOLR can be used to build complex queries to get exactly the datasets we want. In our case, we want conflict data from the ACLED organization in HDX and from the 5 countries (group in CKAN API)

solr_query <- "organization:acled AND groups:(mli OR bfa OR tcd OR mrt OR ner)"
g5_acled <- search_datasets(query = "conflict data",
                            fq = solr_query)
g5_acled
#> [[1]]
#> <HDX Dataset> 331be608-def1-45c5-a9b0-36d4b3b4197e 
#>   Title: Chad - Conflict Data
#>   Name: acled-data-for-chad
#>   Date: 01/01/1997-12/31/2020
#>   Tags (up to 5): hxl, protests, security incidents, violence and conflict
#>   Locations (up to 5): tcd
#>   Resources (up to 5): Conflict Data for Chad, QuickCharts-Conflict Data for Chad
#> 
#> [[2]]
#> <HDX Dataset> 653dc159-097d-4fef-9527-53ee30d132ff 
#>   Title: Niger - Conflict Data
#>   Name: acled-data-for-niger
#>   Date: 01/01/1997-12/31/2020
#>   Tags (up to 5): hxl, protests, security incidents, violence and conflict
#>   Locations (up to 5): ner
#>   Resources (up to 5): Conflict Data for Niger, QuickCharts-Conflict Data for Niger
#> 
#> [[3]]
#> <HDX Dataset> 537ee9a6-ff76-4e00-a9f6-1c7c16ae1628 
#>   Title: Mauritania - Conflict Data
#>   Name: acled-data-for-mauritania
#>   Date: 01/01/1997-12/31/2020
#>   Tags (up to 5): hxl, protests, security incidents, violence and conflict
#>   Locations (up to 5): mrt
#>   Resources (up to 5): Conflict Data for Mauritania, QuickCharts-Conflict Data for Mauritania
#> 
#> [[4]]
#> <HDX Dataset> 5895de63-010c-4716-97cb-fbdd3caf4e3a 
#>   Title: Mali - Conflict Data
#>   Name: acled-data-for-mali
#>   Date: 01/01/1997-12/31/2020
#>   Tags (up to 5): hxl, protests, security incidents, violence and conflict
#>   Locations (up to 5): mli
#>   Resources (up to 5): Conflict Data for Mali, QuickCharts-Conflict Data for Mali
#> 
#> [[5]]
#> <HDX Dataset> 6913ddaf-1ad2-4cad-b178-592b6d49cd61 
#>   Title: Burkina Faso - Conflict Data
#>   Name: acled-data-for-burkina-faso
#>   Date: 01/01/1997-12/31/2020
#>   Tags (up to 5): hxl, protests, security incidents, violence and conflict
#>   Locations (up to 5): bfa
#>   Resources (up to 5): Conflict Data for Burkina Faso, QuickCharts-Conflict Data for Burkina Faso
#> 
#> [[6]]
#> <HDX Dataset> 71d852e4-e41e-4320-a770-9fc2bb87fb64 
#>   Title: ACLED Conflict Data for Africa 1997-2016
#>   Name: acled-conflict-data-for-africa-1997-lastyear
#>   Date: 01/01/2017
#>   Tags (up to 5): geodata, protests, violence and conflict, vulnerable populations
#>   Locations (up to 5): dza, ago, ben, bwa, bfa
#>   Resources (up to 5): ACLED-Version-7-All-Africa-1997-2016_csv_dyadic-file.zip, ACLED-Version-7-All-Africa-1997-2016_dyadic-file.xlsx, ACLED-Version-7-All-Africa-1997-2016_monadic-file_csv.zip, ACLED-Version-7-All-Africa-1997-2016_monadic-file-1.xlsx, ACLED-Version-7-All-Africa-1997-2016_actordyad_csv.zip
#> 
#> attr(,"class")
#> [1] "datasets_list"

We will select the first 5 datasets (our 5 countries) in the list of datasets and bind them together using purrr::map_df and a helper function.

g5_acled <- g5_acled[1:5] ## pick the first 5 the 6th is the Africa wide dataset

## create a helper function to read resources from each dataset
read_acled_data <- function(dataset) {
  dataset %>%
    get_resource(1) %>%
    read_resource(force_download = TRUE)
}

g5_acled_data <- map_df(g5_acled, read_acled_data)
glimpse(g5_acled_data)
#> Rows: 9,534
#> Columns: 31
#> $ data_id          <dbl> 7129882, 7129881, 7126764, 7130217, 7…
#> $ iso              <dbl> 148, 148, 148, 148, 148, 148, 148, 14…
#> $ event_id_cnty    <chr> "CHA1096", "CHA1095", "CHA1093", "CHA…
#> $ event_id_no_cnty <dbl> 1096, 1095, 1093, 1094, 1092, 1091, 1…
#> $ event_date       <date> 2020-06-19, 2020-06-17, 2020-06-13, …
#> $ year             <dbl> 2020, 2020, 2020, 2020, 2020, 2020, 2…
#> $ time_precision   <dbl> 1, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2…
#> $ event_type       <chr> "Battles", "Battles", "Riots", "Battl…
#> $ sub_event_type   <chr> "Armed clash", "Armed clash", "Mob vi…
#> $ actor1           <chr> "Unidentified Armed Group (Chad)", "U…
#> $ assoc_actor_1    <chr> NA, NA, "Vigilante Group (Chad)", NA,…
#> $ inter1           <dbl> 3, 3, 5, 2, 4, 1, 4, 4, 2, 2, 2, 1, 4…
#> $ actor2           <chr> "Militia (Miners)", "Militia (Miners)…
#> $ assoc_actor_2    <chr> NA, NA, NA, NA, "Farmers (Chad)", NA,…
#> $ inter2           <dbl> 3, 3, 7, 4, 7, 8, 7, 4, 1, 1, 1, 7, 4…
#> $ interaction      <dbl> 33, 33, 57, 24, 47, 18, 47, 44, 12, 1…
#> $ region           <chr> "Middle Africa", "Middle Africa", "Mi…
#> $ country          <chr> "Chad", "Chad", "Chad", "Chad", "Chad…
#> $ admin1           <chr> "Tibesti", "Tibesti", "N'Djamena", "L…
#> $ admin2           <chr> "Tibesti Est", "Tibesti Est", "N'Djam…
#> $ admin3           <chr> "Tibesti", "Tibesti", "Ndjamena", "Ng…
#> $ location         <chr> "Zouarke", "Bardai", "NDjamena", "Bar…
#> $ latitude         <dbl> 20.4174, 21.3580, 12.1085, 13.5127, 9…
#> $ longitude        <dbl> 16.2238, 17.0010, 15.0482, 13.8501, 1…
#> $ geo_precision    <dbl> 2, 3, 1, 1, 2, 1, 2, 2, 2, 1, 1, 2, 1…
#> $ source           <chr> "Alwihda (Chad)", "Alwihda (Chad)", "…
#> $ source_scale     <chr> "National", "National", "National", "…
#> $ notes            <chr> "On 19 June 2020, gold miners and sus…
#> $ fatalities       <dbl> 14, 10, 1, 0, 1, 0, 0, 2, 7, 2, 2, 1,…
#> $ timestamp        <dbl> 1592852504, 1592852504, 1592254856, 1…
#> $ iso3             <chr> "TCD", "TCD", "TCD", "TCD", "TCD", "T…

We have all the data we need for our analysis, we just need to aggregate total number fatalities by geographical coordinates, countries and year.

g5_acled_fatalities_loc <- g5_acled_data %>%
  filter(year %in% 2012:2018, fatalities > 0) %>%
  group_by(year, country, latitude, longitude) %>%
  summarise(total_fatalities = sum(fatalities, na.rm = TRUE)) %>%
  arrange(year) %>%
  ungroup()

We can finally use our boundaries (g5_ab), the conflict data (g5_acled_fatalities_loc) with gganimate to dynamically visualize the different fatal incidents in G5 Sahel countries.

g5_ab %>%
  ggplot() +
  geom_sf(fill = "#383838", color = "gray") +
  coord_sf(datum = NA) +
  geom_point(data = g5_acled_fatalities_loc,
             aes(x = longitude,
                 y = latitude,
                 size = total_fatalities,
                 fill = total_fatalities),
             shape = 21,
             color = "transparent") +
  scale_fill_viridis_c(option = "plasma") +
  geom_sf_text(aes(label = admin0Name), color = "gray", fontface = "bold") +
  labs(x = "",
       y = "",
       title = "Fatal events in the Sahel G5",
       subtitle = "for the year {current_frame}",
       caption = "source: ACLED") +
  theme_void() +
  theme(legend.position = "none") +
  transition_manual(year, cumulative = TRUE) +
  shadow_mark()

Session info for this analysis.

Session info
devtools::session_info()
#> ─ Session info ────────────────────────────────────────────────
#>  setting  value                                      
#>  version  R version 4.0.2 Patched (2020-06-22 r78732)
#>  os       Arch Linux                                 
#>  system   x86_64, linux-gnu                          
#>  ui       X11                                        
#>  language (EN)                                       
#>  collate  en_US.UTF-8                                
#>  ctype    en_US.UTF-8                                
#>  tz       Africa/Abidjan                             
#>  date     2020-06-26                                 
#> 
#> ─ Packages ────────────────────────────────────────────────────
#>  package     * version    date       lib
#>  assertthat    0.2.1      2019-03-21 [1]
#>  backports     1.1.8      2020-06-17 [1]
#>  base64enc     0.1-3      2015-07-28 [1]
#>  blob          1.2.1      2020-01-20 [1]
#>  broom         0.5.6      2020-04-20 [1]
#>  callr         3.4.3      2020-03-28 [1]
#>  cellranger    1.1.0      2016-07-27 [1]
#>  class         7.3-17     2020-04-26 [1]
#>  classInt      0.4-3      2020-04-07 [1]
#>  cli           2.0.2      2020-02-28 [1]
#>  colorspace    1.4-1      2019-03-18 [1]
#>  crayon        1.3.4      2017-09-16 [1]
#>  crul          0.9.2.92   2020-06-17 [1]
#>  curl          4.3        2019-12-02 [1]
#>  DBI           1.1.0      2019-12-15 [1]
#>  dbplyr        1.4.4      2020-05-27 [1]
#>  desc          1.2.0      2018-05-01 [1]
#>  devtools      2.3.0      2020-04-10 [1]
#>  digest        0.6.25     2020-02-23 [1]
#>  downlit       0.0.0.9000 2020-06-24 [1]
#>  dplyr       * 1.0.0      2020-05-29 [1]
#>  e1071         1.7-3      2019-11-26 [1]
#>  ellipsis      0.3.1      2020-05-15 [1]
#>  evaluate      0.14       2019-05-28 [1]
#>  fansi         0.4.1      2020-01-08 [1]
#>  farver        2.0.3      2020-01-16 [1]
#>  forcats     * 0.5.0      2020-03-01 [1]
#>  fs            1.4.1      2020-04-04 [1]
#>  generics      0.0.2      2018-11-29 [1]
#>  gganimate   * 1.0.5      2020-02-09 [1]
#>  ggplot2     * 3.3.2      2020-06-19 [1]
#>  gifski        0.8.6      2018-09-28 [1]
#>  glue          1.4.1      2020-05-13 [1]
#>  gtable        0.3.0      2019-03-25 [1]
#>  haven         2.3.1      2020-06-01 [1]
#>  hms           0.5.3      2020-01-08 [1]
#>  hoardr        0.5.2.93   2020-06-08 [1]
#>  htmltools     0.5.0      2020-06-16 [1]
#>  httpcode      0.3.0      2020-04-10 [1]
#>  httr          1.4.1      2019-08-05 [1]
#>  hugodown      0.0.0.9000 2020-06-24 [1]
#>  jsonlite      1.7.0      2020-06-25 [1]
#>  KernSmooth    2.23-17    2020-04-26 [1]
#>  knitr         1.29       2020-06-23 [1]
#>  lattice       0.20-41    2020-04-02 [1]
#>  lifecycle     0.2.0      2020-03-06 [1]
#>  lubridate     1.7.9      2020-06-08 [1]
#>  magrittr      1.5        2014-11-22 [1]
#>  memoise       1.1.0      2017-04-21 [1]
#>  modelr        0.1.8      2020-05-19 [1]
#>  munsell       0.5.0      2018-06-12 [1]
#>  nlme          3.1-148    2020-05-24 [1]
#>  pillar        1.4.4      2020-05-05 [1]
#>  pkgbuild      1.0.8      2020-05-07 [1]
#>  pkgconfig     2.0.3      2019-09-22 [1]
#>  pkgload       1.1.0      2020-05-29 [1]
#>  prettyunits   1.1.1      2020-01-24 [1]
#>  processx      3.4.2      2020-02-09 [1]
#>  progress      1.2.2      2019-05-16 [1]
#>  ps            1.3.3      2020-05-08 [1]
#>  purrr       * 0.3.4      2020-04-17 [1]
#>  R6            2.4.1      2019-11-12 [1]
#>  rappdirs      0.3.1      2016-03-28 [1]
#>  Rcpp          1.0.4.12   2020-06-16 [1]
#>  readr       * 1.3.1      2018-12-21 [1]
#>  readxl        1.3.1      2019-03-13 [1]
#>  remotes       2.1.1      2020-02-15 [1]
#>  reprex        0.3.0      2019-05-16 [1]
#>  rhdx        * 0.1.0.9000 2020-06-14 [1]
#>  rlang         0.4.6      2020-05-02 [1]
#>  rmarkdown     2.3.1      2020-06-24 [1]
#>  rprojroot     1.3-2      2018-01-03 [1]
#>  rstudioapi    0.11       2020-02-07 [1]
#>  rvest         0.3.5      2019-11-08 [1]
#>  scales        1.1.1      2020-05-11 [1]
#>  sessioninfo   1.1.1      2018-11-05 [1]
#>  sf          * 0.9-4      2020-06-19 [1]
#>  stringi       1.4.6      2020-02-17 [1]
#>  stringr     * 1.4.0      2019-02-10 [1]
#>  testthat      2.3.2      2020-03-02 [1]
#>  tibble      * 3.0.1      2020-04-20 [1]
#>  tidyr       * 1.1.0      2020-05-20 [1]
#>  tidyselect    1.1.0      2020-05-11 [1]
#>  tidyverse   * 1.3.0      2019-11-21 [1]
#>  triebeard     0.3.0      2016-08-04 [1]
#>  tweenr        1.0.1      2018-12-14 [1]
#>  units         0.6-7      2020-06-13 [1]
#>  urltools      1.7.3      2019-04-14 [1]
#>  usethis       1.6.1      2020-04-29 [1]
#>  utf8          1.1.4      2018-05-24 [1]
#>  vctrs         0.3.1      2020-06-05 [1]
#>  withr         2.2.0      2020-04-20 [1]
#>  xfun          0.15       2020-06-21 [1]
#>  xml2          1.3.2      2020-04-23 [1]
#>  yaml          2.2.1      2020-02-01 [1]
#>  source                            
#>  CRAN (R 4.0.0)                    
#>  CRAN (R 4.0.2)                    
#>  CRAN (R 4.0.0)                    
#>  CRAN (R 4.0.0)                    
#>  CRAN (R 4.0.0)                    
#>  CRAN (R 4.0.0)                    
#>  CRAN (R 4.0.0)                    
#>  CRAN (R 4.0.2)                    
#>  CRAN (R 4.0.0)                    
#>  CRAN (R 4.0.0)                    
#>  CRAN (R 4.0.0)                    
#>  CRAN (R 4.0.0)                    
#>  local                             
#>  CRAN (R 4.0.0)                    
#>  CRAN (R 4.0.0)                    
#>  CRAN (R 4.0.0)                    
#>  CRAN (R 4.0.0)                    
#>  CRAN (R 4.0.0)                    
#>  CRAN (R 4.0.0)                    
#>  Github (r-lib/downlit@9191e1f)    
#>  CRAN (R 4.0.0)                    
#>  CRAN (R 4.0.0)                    
#>  CRAN (R 4.0.0)                    
#>  CRAN (R 4.0.0)                    
#>  CRAN (R 4.0.0)                    
#>  CRAN (R 4.0.0)                    
#>  CRAN (R 4.0.0)                    
#>  CRAN (R 4.0.0)                    
#>  CRAN (R 4.0.0)                    
#>  CRAN (R 4.0.0)                    
#>  CRAN (R 4.0.2)                    
#>  CRAN (R 4.0.0)                    
#>  CRAN (R 4.0.0)                    
#>  CRAN (R 4.0.0)                    
#>  CRAN (R 4.0.0)                    
#>  CRAN (R 4.0.0)                    
#>  local                             
#>  CRAN (R 4.0.2)                    
#>  CRAN (R 4.0.0)                    
#>  CRAN (R 4.0.0)                    
#>  Github (r-lib/hugodown@f7df565)   
#>  CRAN (R 4.0.2)                    
#>  CRAN (R 4.0.2)                    
#>  CRAN (R 4.0.2)                    
#>  CRAN (R 4.0.2)                    
#>  CRAN (R 4.0.0)                    
#>  CRAN (R 4.0.1)                    
#>  CRAN (R 4.0.0)                    
#>  CRAN (R 4.0.0)                    
#>  CRAN (R 4.0.0)                    
#>  CRAN (R 4.0.0)                    
#>  CRAN (R 4.0.2)                    
#>  CRAN (R 4.0.0)                    
#>  CRAN (R 4.0.0)                    
#>  CRAN (R 4.0.0)                    
#>  CRAN (R 4.0.0)                    
#>  CRAN (R 4.0.0)                    
#>  CRAN (R 4.0.0)                    
#>  CRAN (R 4.0.0)                    
#>  CRAN (R 4.0.0)                    
#>  CRAN (R 4.0.0)                    
#>  CRAN (R 4.0.0)                    
#>  CRAN (R 4.0.0)                    
#>  local                             
#>  CRAN (R 4.0.0)                    
#>  CRAN (R 4.0.0)                    
#>  CRAN (R 4.0.0)                    
#>  CRAN (R 4.0.0)                    
#>  local                             
#>  CRAN (R 4.0.0)                    
#>  Github (rstudio/rmarkdown@b53a85a)
#>  CRAN (R 4.0.0)                    
#>  CRAN (R 4.0.0)                    
#>  CRAN (R 4.0.0)                    
#>  CRAN (R 4.0.0)                    
#>  CRAN (R 4.0.0)                    
#>  Github (r-spatial/sf@0b08ed5)     
#>  CRAN (R 4.0.0)                    
#>  CRAN (R 4.0.0)                    
#>  CRAN (R 4.0.0)                    
#>  CRAN (R 4.0.0)                    
#>  CRAN (R 4.0.0)                    
#>  CRAN (R 4.0.0)                    
#>  CRAN (R 4.0.0)                    
#>  CRAN (R 4.0.0)                    
#>  CRAN (R 4.0.0)                    
#>  CRAN (R 4.0.1)                    
#>  CRAN (R 4.0.0)                    
#>  CRAN (R 4.0.0)                    
#>  CRAN (R 4.0.0)                    
#>  CRAN (R 4.0.1)                    
#>  CRAN (R 4.0.0)                    
#>  CRAN (R 4.0.2)                    
#>  CRAN (R 4.0.0)                    
#>  CRAN (R 4.0.0)                    
#> 
#> [1] /usr/lib/R/library