Global Terrorism Index Analysis (2012–2022)

Exploring Patterns and Trends in Terrorism Impact

Authors

Team Coral

Tee Yu Cheng (2300884)

Lim Jing Chuan Jonathan (2300923)

Miko Lim Yu Hui (2301126)

Ong Jia En Darryl (2301402)

Lim Liang Fan (2300937)

Toh Zheng Yan (2300898)

Huang Wan Ying (2301113)

1. Introduction

This analysis explores the Global Terrorism Index (GTI) data from 2012 to 2022, examining trends and patterns in terrorism impact across countries. The GTI is a comprehensive measure that incorporates incidents, fatalities, injuries, and hostage situations to quantify the impact of terrorism globally.

2. Exploration Data Analysis

2.1. Terrorism Index Overview

The first visualization shows the overall trend of GTI scores for the top 15 most affected countries from 2012 to 2022. This provides a comparative view of how terrorism impact has evolved over time across these nations.

Code
# Plot the data
ggplot(filtered_df, aes(x = Year, y = Score, color = Country)) +
  geom_line(linewidth = 1.2) +   # ← updated here
  geom_point() +
  theme_minimal() +
  labs(title = "Top 15 Countries by Terrorism Index Score (2012–2022)",
       y = "GTI Score",
       x = "Year",
       color = "Country") +
  theme(plot.title = element_text(hjust = 0.5, face = "bold"),
        legend.position = "bottom",
        legend.title = element_text(face = "bold"))

Trend of GTI Scores for Top 15 Most Affected Countries (2012-2022)

Key Insights:

• Afghanistan has consistently maintained the highest GTI score throughout most of the period
• Iraq shows a significant decline in terrorism impact since its peak around 2014-2015
• Several countries show recent increases in their GTI scores, suggesting emerging terrorism hotspots
• The overall pattern reveals fluctuating impacts, indicating the dynamic nature of terrorism threats globally

2.2. Detailed Country Analysis with Severity Classification

This visualization breaks down the terrorism index trends by country with clear severity classifications. The background color bands indicate different severity levels (Severe, High, Moderate, Low), providing context for interpreting the GTI scores.

Code
ggplot(filtered_df, aes(x = Year, y = Score)) +
  # Severity background bands (more visible)
  annotate("rect", xmin = -Inf, xmax = Inf, ymin = 8, ymax = 10,
           fill = "#B22222", alpha = 0.15) +
  annotate("rect", xmin = -Inf, xmax = Inf, ymin = 6, ymax = 8,
           fill = "#FF8C00", alpha = 0.15) +
  annotate("rect", xmin = -Inf, xmax = Inf, ymin = 4, ymax = 6,
           fill = "#FFD700", alpha = 0.15) +
  annotate("rect", xmin = -Inf, xmax = Inf, ymin = 0, ymax = 4,
           fill = "#90EE90", alpha = 0.15) +
  
  # Add labels to indicate severity zones
  annotate("text", x = 2013, y = 9, label = "Severe", color = "#8B0000", size = 4, fontface = "bold") +
  annotate("text", x = 2013, y = 7, label = "High", color = "#FF8C00", size = 4, fontface = "bold") +
  annotate("text", x = 2013, y = 5, label = "Moderate", color = "#DAA520", size = 4, fontface = "bold") +
  annotate("text", x = 2013, y = 2, label = "Low", color = "#228B22", size = 4, fontface = "bold") +

  # Main line chart
  geom_line(color = "#000000", linewidth = 1.2) +
  geom_point(color = "#000000", size = 1.2) +
  
  # Faceted by country
  facet_wrap(~Country, ncol = 5) +
  theme_minimal(base_size = 12) +
  labs(
    title = "Terrorism Index Trends by Country (2012–2022)",
    subtitle = "GTI Scores Categorized by Severity Levels",
    x = "Year",
    y = "GTI Score (0–10)\nHigher = More Impact from Terrorism"
  ) +
  theme(
    plot.title = element_text(size = 16, face = "bold", hjust = 0.5),
    plot.subtitle = element_text(size = 13, hjust = 0.5),
    strip.text = element_text(size = 11, face = "bold"),
    axis.text.x = element_text(angle = 45, hjust = 1),
    panel.grid.minor = element_blank()
  )

Terrorism Index Trends by Country (2012–2022), with Severity Levels

Key Insights:

• Most countries have experienced periods in the “High” to “Severe” range during the decade
• Some countries show clear improvement patterns (Iraq, Syria, Nigeria)
• Others demonstrate concerning upward trends (Burkina Faso, Mali)
• Afghanistan has remained consistently in the “Severe” category
• The severity classification provides important context for understanding the relative impact of terrorism

2.3. Impact Analysis: Casualties and Incidents

2.3.1. Top 15 Countries by Total Fatalities

This visualization shows the countries with the highest number of terrorism-related fatalities over the 2012-2022 period. The number of fatalities is a direct measure of the human cost of terrorism.

Code
top_deaths <- combined_raw_df %>%
  group_by(Country) %>%
  summarise(Total_Deaths = sum(Fatalities, na.rm = TRUE)) %>%
  arrange(desc(Total_Deaths)) %>%
  slice_head(n = 15)

ggplot(top_deaths, aes(x = reorder(Country, Total_Deaths), y = Total_Deaths)) +
  geom_col(fill = "darkred") +
  # Add value labels at the end of each bar
  geom_text(aes(label = format(Total_Deaths, big.mark = ",")), 
            hjust = -0.2, color = "black", fontface = "bold", size = 3.5) +
  coord_flip(clip = "off") +  # Prevent clipping of labels
  scale_y_continuous(limits = function(x) c(0, x[2] * 1.1)) +  # Expand y-axis to make room for labels
  labs(title = "Top 15 Countries by Total Fatalities (2012–2022)",
       x = "Country", y = "Total Fatalities") +
  theme_minimal() +
  theme(
    plot.title = element_text(face = "bold", hjust = 0.5),
    axis.text.y = element_text(face = "bold"),
    plot.margin = margin(5.5, 30, 5.5, 5.5)  # Add right margin for labels
  )

Countries with Highest Terrorism-Related Fatalities (2012-2022)

2.3.2. Top 15 Countries by Total Injuries

Beyond fatalities, injuries represent another significant impact of terrorism. This visualization shows the countries with the highest number of terrorism-related injuries, which often outnumber fatalities and create long-term burdens on healthcare systems.

Code
top_injuries <- combined_raw_df %>%
  group_by(Country) %>%
  summarise(Total_Injuries = sum(Injuries, na.rm = TRUE)) %>%
  arrange(desc(Total_Injuries)) %>%
  slice_head(n = 15)

ggplot(top_injuries, aes(x = reorder(Country, Total_Injuries), y = Total_Injuries)) +
  geom_col(fill = "orange") +
  # Add value labels at the end of each bar
  geom_text(aes(label = format(Total_Injuries, big.mark = ",")), 
            hjust = -0.2, color = "black", fontface = "bold", size = 3.5) +
  coord_flip(clip = "off") +  # Prevent clipping of labels
  scale_y_continuous(limits = function(x) c(0, x[2] * 1.1)) +  # Expand y-axis to make room for labels
  labs(title = "Top 15 Countries by Total Injuries (2012–2022)",
       x = "Country", y = "Total Injuries") +
  theme_minimal() +
  theme(
    plot.title = element_text(face = "bold", hjust = 0.5),
    axis.text.y = element_text(face = "bold"),
    plot.margin = margin(5.5, 30, 5.5, 5.5)  # Add right margin for labels
  )

Countries with Highest Terrorism-Related Injuries (2012-2022)

2.3.3. Top 15 Countries by Total Incidents

The number of terrorist incidents provides a measure of the frequency of attacks, regardless of their scale. This visualization highlights countries experiencing the highest number of terrorism events during the study period.

Code
top_incidents <- combined_raw_df %>%
  group_by(Country) %>%
  summarise(Total_Incidents = sum(Incidents, na.rm = TRUE)) %>%
  arrange(desc(Total_Incidents)) %>%
  slice_head(n = 15)

ggplot(top_incidents, aes(x = reorder(Country, Total_Incidents), y = Total_Incidents)) +
  geom_col(fill = "steelblue") +
  # Add value labels at the end of each bar
  geom_text(aes(label = format(Total_Incidents, big.mark = ",")), 
            hjust = -0.2, color = "black", fontface = "bold", size = 3.5) +
  coord_flip(clip = "off") +  # Prevent clipping of labels
  scale_y_continuous(limits = function(x) c(0, x[2] * 1.1)) +  # Expand y-axis to make room for labels
  labs(title = "Top 15 Countries by Total Incidents (2012–2022)",
       x = "Country", y = "Total Incidents") +
  theme_minimal() +
  theme(
    plot.title = element_text(face = "bold", hjust = 0.5),
    axis.text.y = element_text(face = "bold"),
    plot.margin = margin(5.5, 30, 5.5, 5.5)  # Add right margin for labels
  )

Countries with Highest Number of Terrorist Incidents (2012-2022)

2.3.4. Top 15 Countries by Total Hostages

Code
top_hostages <- combined_raw_df %>%
  group_by(Country) %>%
  summarise(Total_Hostages = sum(Hostages, na.rm = TRUE)) %>%
  arrange(desc(Total_Hostages)) %>%
  slice_head(n = 15)

ggplot(top_hostages, aes(x = reorder(Country, Total_Hostages), y = Total_Hostages)) +
  geom_col(fill = "purple") +
  # Add value labels at the end of each bar
  geom_text(aes(label = format(Total_Hostages, big.mark = ",")), 
            hjust = -0.2, color = "black", fontface = "bold", size = 3.5) +
  coord_flip(clip = "off") +  # Prevent clipping of labels
  scale_y_continuous(limits = function(x) c(0, x[2] * 1.1)) +  # Expand y-axis to make room for labels
  labs(title = "Top 15 Countries by Total Hostages (2012–2022)",
       x = "Country", y = "Total Hostages Taken") +
  theme_minimal() +
  theme(
    plot.title = element_text(face = "bold", hjust = 0.5),
    axis.text.y = element_text(face = "bold"),
    plot.margin = margin(5.5, 30, 5.5, 5.5)  # Add right margin for labels
  )

Countries with Highest Number of Hostages in Terrorist Incidents (2012-2022)

Key Insights from Impact Analysis:

• Fatalities: Iraq, Afghanistan, and Nigeria have suffered the highest number of terrorism-related deaths
• Injuries: Iraq and Afghanistan also lead in injuries, but Pakistan ranks higher in injuries than in fatalities
• Incidents: Iraq experiences the most terrorism incidents, followed by Afghanistan and Pakistan
• Hostages: Nigeria stands out with significantly more hostages than other countries, likely due to specific tactics used by terrorist groups operating there
• Different countries show different patterns of terrorism impact (e.g., some have high fatality-to-incident ratios while others show more incidents with fewer casualties)

2.5. Multi-Dimensional Analysis

This bubble chart provides a multi-dimensional view of terrorism impact, plotting fatalities against injuries while using bubble size to represent the average GTI score. This visualization helps identify countries that are disproportionately affected across different impact measures.

Code
bubble_data <- combined_raw_df %>%
  group_by(Country) %>%
  summarise(Fatalities = sum(Fatalities, na.rm = TRUE),
            Injuries = sum(Injuries, na.rm = TRUE),
            GTI = mean(Score, na.rm = TRUE)) %>%
  filter(Fatalities > 0 & Injuries > 0)

ggplot(bubble_data, aes(x = Fatalities, y = Injuries, size = GTI, label = Country)) +
  geom_point(alpha = 0.6, color = "darkblue") +
  geom_text(check_overlap = TRUE, size = 3, vjust = 1.5) +
  scale_size_continuous(range = c(2, 10)) +
  labs(title = "Bubble Chart: Fatalities vs Injuries by Country",
       x = "Total Fatalities", y = "Total Injuries", size = "Avg. GTI Score") +
  theme_minimal()

Multi-Dimensional Analysis of Terrorism Impact by Country (2012-2022)
Code
  theme(
    plot.title = element_text(face = "bold", hjust = 0.5),
    plot.subtitle = element_text(hjust = 0.5),
    legend.position = "right"
  )
List of 3
 $ legend.position: chr "right"
 $ plot.title     :List of 11
  ..$ family       : NULL
  ..$ face         : chr "bold"
  ..$ colour       : NULL
  ..$ size         : NULL
  ..$ hjust        : num 0.5
  ..$ vjust        : NULL
  ..$ angle        : NULL
  ..$ lineheight   : NULL
  ..$ margin       : NULL
  ..$ debug        : NULL
  ..$ inherit.blank: logi FALSE
  ..- attr(*, "class")= chr [1:2] "element_text" "element"
 $ plot.subtitle  :List of 11
  ..$ family       : NULL
  ..$ face         : NULL
  ..$ colour       : NULL
  ..$ size         : NULL
  ..$ hjust        : num 0.5
  ..$ vjust        : NULL
  ..$ angle        : NULL
  ..$ lineheight   : NULL
  ..$ margin       : NULL
  ..$ debug        : NULL
  ..$ inherit.blank: logi FALSE
  ..- attr(*, "class")= chr [1:2] "element_text" "element"
 - attr(*, "class")= chr [1:2] "theme" "gg"
 - attr(*, "complete")= logi FALSE
 - attr(*, "validate")= logi TRUE

Key Insights from Multi-Dimensional Analysis:

• Iraq and Afghanistan stand as extreme outliers, with exceptionally high values across all three dimensions
• Most countries cluster in the lower ranges for both fatalities and injuries
• Some countries show disproportionate ratios between fatalities and injuries
• The relationship between GTI score and casualty figures is generally consistent, with higher casualties correlating with higher GTI scores
• A few countries have relatively high GTI scores despite moderate casualty figures, suggesting other factors (like property damage or psychological impact) influence their GTI ranking

3. Data Pre-Processing

Key Metric: Fatality Rate

Definition: Average deaths per attack = Fatalities ÷ Incidents.
Why it matters: Normalizes for attack frequency so you can compare how deadly incidents are across countries and over time.
Interpretation: An increasing rate signals more severe attacks or reduced survivability; a declining rate suggests less-lethal tactics or improved emergency response.

3.1. Data Ingestion

Data Ingestion: Load the raw “Combined raw” sheet into R using read_excel, preserving the original structure so we can inspect and verify the incoming data before any transformations.

Code
library(readxl)
data_path <- "data/Global Terrorism Index 2023.xlsx"

raw_df <- read_excel(data_path, sheet = "Combined raw")
head(raw_df)
# A tibble: 6 × 9
  iso3c Country      Rank Score Incidents Fatalities Injuries Hostages  Year
  <chr> <chr>       <dbl> <dbl>     <dbl>      <dbl>    <dbl>    <dbl> <dbl>
1 IRQ   Iraq            1  9.60      1288       2086     5050       16  2012
2 PAK   Pakistan        2  9.15       638       1322     2297      160  2012
3 AFG   Afghanistan     3  9.13       507       1511     2612       67  2012
4 SYR   Syria           4  8.24       168       1014     1833       71  2012
5 YEM   Yemen           5  8.10       219        651      798      121  2012
6 NGA   Nigeria         6  8.10       212        767      496        9  2012

Initial Data Snapshot:

- The raw “Combined raw” sheet contains 9 columns: iso3c, Country, Rank, Score, Incidents, Fatalities, Injuries, Hostages, and Year.
- The first six rows for 2012 list Iraq, Pakistan, Afghanistan, Syria, Yemen, and Nigeria—showing their 2012 GTI rank, score, and casualty figures.
- Confirms successful ingestion and expected structure before any cleaning or transformation.

3.2. Cleaning & Normalization

Cleaning & Normalization: Standardize column names to snake_case, remove empty or “Total” rows, trim whitespace in country, convert all metric columns (incidents, fatalities, injuries, hostages, score) to numeric types, replace any missing values with zeros, and drop exact duplicate rows to ensure a consistent dataset.

Code
library(dplyr)
library(janitor)

Attaching package: 'janitor'
The following objects are masked from 'package:stats':

    chisq.test, fisher.test
Code
library(stringr)

clean_df <- raw_df %>%
  clean_names() %>%                                 # snake_case column names
  filter(
    !is.na(country),
    country != "",
    !str_detect(country, regex("total|all", ignore_case = TRUE))
  ) %>%
  mutate(
    country    = str_squish(country),               # trim extra spaces
    year       = as.integer(year),
    incidents  = as.numeric(incidents),
    fatalities = as.numeric(fatalities),
    injuries   = as.numeric(injuries),
    hostages   = as.numeric(hostages),
    score      = as.numeric(score)
  ) %>%
  replace_na(list(                                  # missing counts → 0
    incidents  = 0,
    fatalities = 0,
    injuries   = 0,
    hostages   = 0
  )) %>%
  distinct(country, year, .keep_all = TRUE)         # drop exact duplicates

head(clean_df)
# A tibble: 6 × 9
  iso3c country      rank score incidents fatalities injuries hostages  year
  <chr> <chr>       <dbl> <dbl>     <dbl>      <dbl>    <dbl>    <dbl> <int>
1 IRQ   Iraq            1  9.60      1288       2086     5050       16  2012
2 PAK   Pakistan        2  9.15       638       1322     2297      160  2012
3 AFG   Afghanistan     3  9.13       507       1511     2612       67  2012
4 SYR   Syria           4  8.24       168       1014     1833       71  2012
5 YEM   Yemen           5  8.10       219        651      798      121  2012
6 NGA   Nigeria         6  8.10       212        767      496        9  2012

3.3. Post-cleaning Validation

Validate Cleaning Results: Verify that column types, row counts, and missing‐value replacements are as expected. We compare before/after dimensions, check for duplicates, and summarize any remaining NAs.

Code
library(dplyr)

# 1. Compare dimensions before & after
cat("Raw rows:", nrow(raw_df), "→ Clean rows:", nrow(clean_df), "\n")
Raw rows: 1793 → Clean rows: 1793 
Code
cat("Raw cols:", ncol(raw_df), "→ Clean cols:", ncol(clean_df), "\n\n")
Raw cols: 9 → Clean cols: 9 
Code
# 2. Check for any duplicate rows remaining
cat("Duplicates in clean_df:", sum(duplicated(clean_df)), "\n\n")
Duplicates in clean_df: 0 
Code
# 3. Summarize NA counts by column
na_summary <- clean_df %>%
  summarise(across(everything(), ~ sum(is.na(.))))
print(na_summary)
# A tibble: 1 × 9
  iso3c country  rank score incidents fatalities injuries hostages  year
  <int>   <int> <int> <int>     <int>      <int>    <int>    <int> <int>
1     0       0     0     0         0          0        0        0     0
Code
# 4. Glimpse the cleaned structure
glimpse(clean_df)
Rows: 1,793
Columns: 9
$ iso3c      <chr> "IRQ", "PAK", "AFG", "SYR", "YEM", "NGA", "SOM", "IND", "TH…
$ country    <chr> "Iraq", "Pakistan", "Afghanistan", "Syria", "Yemen", "Niger…
$ rank       <dbl> 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, …
$ score      <dbl> 9.599967, 9.152620, 9.134265, 8.238079, 8.098513, 8.098342,…
$ incidents  <dbl> 1288, 638, 507, 168, 219, 212, 166, 219, 199, 219, 157, 119…
$ fatalities <dbl> 2086, 1322, 1511, 1014, 651, 767, 446, 150, 184, 157, 188, …
$ injuries   <dbl> 5050, 2297, 2612, 1833, 798, 496, 427, 256, 493, 309, 502, …
$ hostages   <dbl> 16, 160, 67, 71, 121, 9, 1, 41, 0, 3, 89, 21, 29, 1, 6, 3, …
$ year       <int> 2012, 2012, 2012, 2012, 2012, 2012, 2012, 2012, 2012, 2012,…

Post-Cleaning Validation:

Row & Column Consistency: Retained all 1,793 rows and 9 columns—no unintended data loss.

Duplicates Removed: Zero duplicate entries, ensuring each country–year is unique.

No Missing Values: All incidents, fatalities, injuries, and hostages fields now have zero NAs.

Correct Data Types: year is integer and all metric columns are numeric, ready for reliable aggregation and analysis.

3.4. Filtering & Period Selection

Filtering & Period Selection: Restrict the cleaned dataset to the years 2012–2022 (inclusive), so that all subsequent analysis focuses on our target time window.

Code
# 1. Keep only 2012 through 2022
combined_raw_df <- clean_df %>%
  filter(year >= 2012, year <= 2022)

# 2. Verify the operation
cat("Year range after filter:", range(combined_raw_df$year), "\n")
Year range after filter: 2012 2022 
Code
head(combined_raw_df)
# A tibble: 6 × 9
  iso3c country      rank score incidents fatalities injuries hostages  year
  <chr> <chr>       <dbl> <dbl>     <dbl>      <dbl>    <dbl>    <dbl> <int>
1 IRQ   Iraq            1  9.60      1288       2086     5050       16  2012
2 PAK   Pakistan        2  9.15       638       1322     2297      160  2012
3 AFG   Afghanistan     3  9.13       507       1511     2612       67  2012
4 SYR   Syria           4  8.24       168       1014     1833       71  2012
5 YEM   Yemen           5  8.10       219        651      798      121  2012
6 NGA   Nigeria         6  8.10       212        767      496        9  2012

Period Selection Validation:

• Dataset now spans only the years 2012 through 2022 as intended.
• Confirms our analysis will focus on a consistent 11-year window.
• Underlying record count remains unchanged, preserving full coverage within this period.

3.5. Selecting Top 8 Countries by Total Fatalities

Identify the eight countries with the highest cumulative fatalities and keep only their records.

Code
top8_countries <- combined_raw_df %>%
  group_by(country) %>%
  summarise(total_fatalities = sum(fatalities, na.rm=TRUE), .groups="drop") %>%
  slice_max(total_fatalities, n=8) %>%
  pull(country)

filtered_df <- combined_raw_df %>%
  filter(country %in% top8_countries)

top8_countries
[1] "Iraq"         "Afghanistan"  "Nigeria"      "Pakistan"     "Somalia"     
[6] "Syria"        "Burkina Faso" "Mali"        

Top 8 Countries by Total Fatalities (2012–2022):
- Iraq, Afghanistan, Nigeria, Syria, and Pakistan consistently record the highest terrorism-related death tolls each year (IEP GTI map :contentReferenceoaicite:0).
- Somalia remains among the worst-hit due to the persistent al-Shabaab insurgency and large-scale attacks (UN experts report :contentReferenceoaicite:1).
- Burkina Faso and Mali have surged into the top eight as jihadist violence in the Sahel intensifies—this region now accounts for over 40 % of global terrorism fatalities (GTI 2024 Briefing PDF :contentReferenceoaicite:2).

3.6. Summarise Annual Fatalities

Summarise Annual Fatalities: Aggregate total fatalities by country and year for our selected top-8 countries, convert counts into “thousands,” and print the full 2012–2022 series.

Code
library(dplyr)

annual_fat_df <- filtered_df %>%
  group_by(country, year) %>%
  summarise(
    annual_fatalities = sum(fatalities, na.rm = TRUE),
    .groups = "drop"
  ) %>%
  mutate(
    fatalities_k = annual_fatalities / 1000
  )

# Print all 88 rows to verify
print(annual_fat_df, n = nrow(annual_fat_df))
# A tibble: 88 × 4
   country       year annual_fatalities fatalities_k
   <chr>        <int>             <dbl>        <dbl>
 1 Afghanistan   2012              1511        1.51 
 2 Afghanistan   2013               923        0.923
 3 Afghanistan   2014              1143        1.14 
 4 Afghanistan   2015              1008        1.01 
 5 Afghanistan   2016               643        0.643
 6 Afghanistan   2017              1256        1.26 
 7 Afghanistan   2018              1624        1.62 
 8 Afghanistan   2019              1194        1.19 
 9 Afghanistan   2020              1292        1.29 
10 Afghanistan   2021              1499        1.50 
11 Afghanistan   2022               633        0.633
12 Burkina Faso  2012                 0        0    
13 Burkina Faso  2013                 0        0    
14 Burkina Faso  2014                 0        0    
15 Burkina Faso  2015                 4        0.004
16 Burkina Faso  2016                53        0.053
17 Burkina Faso  2017                72        0.072
18 Burkina Faso  2018               144        0.144
19 Burkina Faso  2019               682        0.682
20 Burkina Faso  2020               666        0.666
21 Burkina Faso  2021               759        0.759
22 Burkina Faso  2022              1135        1.14 
23 Iraq          2012              2086        2.09 
24 Iraq          2013              3980        3.98 
25 Iraq          2014              3206        3.21 
26 Iraq          2015              2974        2.97 
27 Iraq          2016              4514        4.51 
28 Iraq          2017              1732        1.73 
29 Iraq          2018              1083        1.08 
30 Iraq          2019               533        0.533
31 Iraq          2020               464        0.464
32 Iraq          2021               540        0.54 
33 Iraq          2022               174        0.174
34 Mali          2012                45        0.045
35 Mali          2013                45        0.045
36 Mali          2014                36        0.036
37 Mali          2015               181        0.181
38 Mali          2016               144        0.144
39 Mali          2017               296        0.296
40 Mali          2018               340        0.34 
41 Mali          2019               389        0.389
42 Mali          2020               404        0.404
43 Mali          2021               604        0.604
44 Mali          2022               944        0.944
45 Nigeria       2012               767        0.767
46 Nigeria       2013               931        0.931
47 Nigeria       2014              2101        2.10 
48 Nigeria       2015              2003        2.00 
49 Nigeria       2016               518        0.518
50 Nigeria       2017               794        0.794
51 Nigeria       2018               642        0.642
52 Nigeria       2019               688        0.688
53 Nigeria       2020               865        0.865
54 Nigeria       2021               497        0.497
55 Nigeria       2022               385        0.385
56 Pakistan      2012              1322        1.32 
57 Pakistan      2013              1503        1.50 
58 Pakistan      2014               996        0.996
59 Pakistan      2015               658        0.658
60 Pakistan      2016               631        0.631
61 Pakistan      2017               632        0.632
62 Pakistan      2018               502        0.502
63 Pakistan      2019               250        0.25 
64 Pakistan      2020               263        0.263
65 Pakistan      2021               292        0.292
66 Pakistan      2022               643        0.643
67 Somalia       2012               446        0.446
68 Somalia       2013               264        0.264
69 Somalia       2014               256        0.256
70 Somalia       2015               335        0.335
71 Somalia       2016               760        0.76 
72 Somalia       2017              1535        1.54 
73 Somalia       2018               833        0.833
74 Somalia       2019               693        0.693
75 Somalia       2020               671        0.671
76 Somalia       2021               661        0.661
77 Somalia       2022               755        0.755
78 Syria         2012              1014        1.01 
79 Syria         2013               907        0.907
80 Syria         2014               545        0.545
81 Syria         2015               226        0.226
82 Syria         2016               531        0.531
83 Syria         2017               376        0.376
84 Syria         2018               323        0.323
85 Syria         2019               368        0.368
86 Syria         2020               746        0.746
87 Syria         2021               494        0.494
88 Syria         2022               447        0.447

Fatality Rate Calculation:
• Groups the top-8 countries by country and year.
• Sums fatalities into annual_fatalities (with na.rm = TRUE).
• Drops years with zero incidents to avoid undefined rates.
• Converts to thousands fatalities_k = annual_fatalities / 1000.
• Prints all 88 rows (2012–2022) so you can verify every country–year rate before plotting.

4. Visualizing Annual Fatalities

Visualizing Annual Fatalities: A stacked‐area chart showing total yearly fatalities (in thousands) for our top 8 countries over 2012–2022.

Code
library(dplyr)
library(ggplot2)
library(scales)
library(tibble)
library(grid)

# 1) Data prep
df <- filtered_df %>%
  group_by(country, year) %>%
  summarise(fatalities_k = sum(fatalities, na.rm = TRUE) / 1000, .groups = "drop")

# 2) Stack ordering
order_levels <- df %>%
  group_by(country) %>%
  summarise(total = sum(fatalities_k), .groups = "drop") %>%
  arrange(total) %>%
  pull(country)
df$country <- factor(df$country, levels = order_levels)

# 3) Global totals
top_k <- df %>%
  group_by(year) %>%
  summarise(global_k = sum(fatalities_k), .groups = "drop")

# 4) Anchor labels for 2013, 2016, 2019
annot_years <- top_k %>%
  filter(year %in% c(2013, 2016, 2019)) %>%
  mutate(label = if_else(
    year == 2013,
    paste0("Peak: ", round(global_k, 1), " k"),
    paste0(round(global_k, 1), " k")
  ))

# 5) 2020 rebound values
y2020   <- top_k$global_k[top_k$year == 2020]
label20 <- paste0(round(y2020, 1), " k")

# 6) Key events
events <- tribble(
  ~year, ~date,         ~label,                         ~ypos,
  2013,  "21 Aug 2013",  "Ghouta chemical attack",       top_k$global_k[top_k$year == 2013] + 1.5,
  2016,  "17 Oct 2016",  "Battle of Mosul begins",       top_k$global_k[top_k$year == 2016] + 1.5,
  2019,  "27 Oct 2019",  "Baghdadi killed by US forces", top_k$global_k[top_k$year == 2019] + 2.5
)

# 7) Palette
okabe_ito <- c(
  "Iraq"         = "#E69F00",
  "Afghanistan"  = "#56B4E9",
  "Nigeria"      = "#009E73",
  "Pakistan"     = "#F0E442",
  "Somalia"      = "#0072B2",
  "Burkina Faso" = "#D55E00",
  "Mali"         = "#CC79A7",
  "Syria"        = "#999999"
)

# 8) Plot
ggplot(df, aes(x = year, y = fatalities_k, fill = country)) +
  # a) stacked areas
  geom_area(color = "white", size = 0.2, alpha = 0.85) +
  
  # b) global total line (inherit.aes=FALSE so it won't try to map fill=country)
  geom_line(data = top_k,
            aes(x = year, y = global_k, color = "Global total"),
            inherit.aes = FALSE,
            size = 1) +
  
  # c) anchor points and labels
  geom_point(data = annot_years,
             aes(x = year, y = global_k),
             inherit.aes = FALSE, color = "red", size = 3) +
  geom_text(data = annot_years,
            aes(x = year, y = global_k, label = label),
            inherit.aes = FALSE,
            nudge_y = 0.5, fontface = "bold", size = 4, color = "red") +
  
  # d) downtrend arrow
  geom_segment(data = tibble(),
               aes(x    = 2016,
                   y    = top_k$global_k[top_k$year == 2016] + 0.8,
                   xend = 2019,
                   yend = top_k$global_k[top_k$year == 2019] + 0.8),
               inherit.aes = FALSE,
               arrow = arrow(length = unit(0.25, "cm"), type = "closed"),
               color = "red", size = 0.8) +
  annotate("text",
           x     = 2017.5,
           y     = approx(top_k$year, top_k$global_k, xout = 2017.5)$y + 1.3,
           label = "Downtrend",
           angle = -23,
           fontface = "bold", size = 4, color = "red", hjust = 0.5) +
  
  # e) 2020 rebound vertical
  geom_vline(xintercept = 2020, linetype = "dashed", color = "gray30") +
  
  # f) 2020 rebound point, value, and label (each with its own one-row data)
  geom_point(data = tibble(year = 2020, y = y2020),
             aes(x = year, y = y),
             inherit.aes = FALSE, color = "red", size = 3) +
  geom_text(data = tibble(year = 2020, y = y2020, label = label20),
            aes(x = year, y = y, label = label),
            inherit.aes = FALSE,
            nudge_y = 0.3, fontface = "bold", size = 4, color = "red") +
  geom_label(data = tibble(year = 2020, y = y2020 + 0.9, label = "Affiliate Rebound"),
             aes(x = year, y = y, label = label),
             inherit.aes = FALSE,
             size = 3.5, fontface = "bold",
             fill = "white", color = "gray20", label.size = 0.05) +
  
  # g) event vlines and labels
  geom_vline(data = events,
             aes(xintercept = year),
             linetype = "dashed", color = "gray30") +
  geom_label(data = events,
             aes(x = year, y = ypos, label = paste0(label, "\n", date)),
             inherit.aes = FALSE,
             size = 4, fontface = "bold",
             fill = "white", color = "gray20", label.size = 0.05) +
  
  # h) scales & legend
  scale_fill_manual(name = "Country", values = okabe_ito) +
  scale_color_manual(NULL,
                     values = c("Global total" = "black"),
                     guide = guide_legend(override.aes = list(linetype = 1, size = 1.2))) +
  scale_x_continuous(breaks = 2012:2022) +
  scale_y_continuous("Fatalities (thousands)",
                     expand = expansion(mult = c(0.05, 0.15))) +
  
  # i) titles, subtitle, source
  labs(
    title    = "Global Terrorism Fatalities in the Highest-Impact Countries (2012–2022)",
    subtitle = "Cumulative deaths peaked in 2013; a pronounced decline followed the Battle of Mosul and ISIS leadership loss, with a modest rebound in 2020",
    caption  = "Source: Kaggle (Kaggle, 2023): Global Terrorism Index 2023 (2012–2022)",
    x        = "Year"
  ) +
  
  # j) theme
  theme_minimal(base_size = 14) +
  theme(
    plot.title            = element_text(hjust = 0.5, face = "bold", size = 16),
    plot.subtitle         = element_text(hjust = 0.5, size = 12),
    plot.caption.position = "plot",
    plot.caption          = element_text(hjust = 1, face = "italic", size = 10),
    legend.position       = "bottom",
    panel.grid.minor      = element_blank()
  )

Top 8 Countries: Terrorism Fatalities (2012–2022) – ISIS Surge & Decline plus 2020 Rebound (Fixed)

Key Insights from Annual Fatalities (2012–2022):

Global Peak & Major Surges: Total terrorism deaths hit their highest point around 2013, driven largely by ISIS’s rise (declared caliphate in June 2014) and the Ghouta chemical attack (Aug 2013). A secondary surge in 2016 coincides with the Battle of Mosul.

Steady Decline Post-2016: After Mosul, overall fatalities fell sharply through 2017–2019, culminating in the killing of ISIS leader Baghdadi in October 2019.

Recent Uptick & Shifts: From 2020 onward fatalities stabilized at lower levels, with a mild rebound in 2021 as the Taliban recaptured Kabul.

Country Contributions: Iraq and Nigeria remain the largest contributors throughout, followed by Afghanistan and Somalia, while the Sahel states (Burkina Faso, Mali) gradually account for a bigger share in later years.

5. Conclusion

This analysis has examined the Global Terrorism Index data from multiple perspectives, revealing important patterns in how terrorism has impacted different countries over the past decade. The visualizations highlight both the geographic concentration of terrorism and its evolving nature over time.

Several key findings emerge:

  • Terrorism impact is highly concentrated in a small number of countries, particularly in the Middle East, South Asia, and parts of Africa

  • The overall global trend shows a peak in terrorism impact around 2013–2016, followed by a general decline

  • Different countries show distinct patterns of improvement or deterioration in their terrorism situation

  • The various dimensions of terrorism impact (fatalities, injuries, incidents, hostages) affect countries in different proportions

  • The severity classification framework provides valuable context for interpreting GTI scores

    These insights can inform policy discussions about international security cooperation, humanitarian assistance, and targeted counter-terrorism efforts in the most affected regions.

6. Additional Information

Interactive Plot

Code
library(dplyr)
library(plotly)
library(purrr)
library(tibble)

# 1) Data prep
df_plot <- filtered_df %>%
  group_by(country, year) %>%
  summarise(fatalities_k = sum(fatalities, na.rm = TRUE) / 1000, .groups = "drop")

top_k <- df_plot %>%
  group_by(year) %>%
  summarise(global_k = sum(fatalities_k), .groups = "drop")

# 2) Palette & stacking order
okabe_ito <- c(
  "Iraq"         = "#E69F00",
  "Afghanistan"  = "#56B4E9",
  "Nigeria"      = "#009E73",
  "Pakistan"     = "#F0E442",
  "Somalia"      = "#0072B2",
  "Burkina Faso" = "#D55E00",
  "Mali"         = "#CC79A7",
  "Syria"        = "#999999"
)
order_levels <- df_plot %>%
  group_by(country) %>%
  summarise(total = sum(fatalities_k), .groups = "drop") %>%
  arrange(total) %>%
  pull(country)

# 3) Initialize plotly
p <- plot_ly()

# 4) Vertical dotted guides for each year
for (xv in 2012:2022) {
  p <- p %>% add_segments(
    x = xv, xend = xv,
    y = 0, yend = max(top_k$global_k) * 1.2,
    line = list(dash = "dot", color = "gray80", width = 0.5),
    showlegend = FALSE, hoverinfo = "none"
  )
}

# 5) Stacked areas (no individual hover)
for (ctry in rev(order_levels)) {
  sub <- filter(df_plot, country == ctry)
  p <- p %>% add_trace(
    x = sub$year,
    y = sub$fatalities_k,
    name = ctry,
    type = "scatter",
    mode = "none",
    stackgroup = "one",
    fillcolor = okabe_ito[ctry],
    hoverinfo = "none"
  )
}

# 6) Global total line — hover turned off here
p <- p %>% add_trace(
  data      = top_k,
  x         = ~year,
  y         = ~global_k,
  name      = "Global total",
  type      = "scatter",
  mode      = "lines",
  line      = list(color = "black", width = 2),
  hoverinfo = "none"    # <- disable its own popup
)

# 7) Consolidated tooltip at each year
tooltip_df <- top_k %>%
  mutate(
    tooltip = map_chr(year, function(y) {
      rows <- filter(df_plot, year == y)
      # build lines: Year + Global + each country
      hdr  <- paste0("Year: ", y, "<br>Global total: ", round(global_k[year==y],2), " k deaths")
      cntr <- map_chr(order_levels, function(ct) {
        val <- rows$fatalities_k[rows$country == ct]
        sprintf("<span style='color:%s'>&#9632;</span> %s: %.2f k deaths", 
                okabe_ito[ct], ct, val)
      })
      paste(c(hdr, cntr), collapse = "<br>")
    })
  )

p <- p %>% add_trace(
  data       = tooltip_df,
  x          = ~year,
  y          = max(top_k$global_k) * 1.2,  # above the stack
  type       = "scatter",
  mode       = "markers",
  marker     = list(size = 0),
  hoverinfo  = "text",
  text       = ~tooltip,
  hoverlabel = list(align = "left", font = list(size = 10)),
  showlegend = FALSE
)

# 8) Final layout
p %>% layout(
  title     = list(text = "Top 8 Countries: Terrorism Fatalities (2012–2022)", x = 0.5),
  xaxis     = list(title = "Year", tickmode = "array", tickvals = 2012:2022),
  yaxis     = list(title = "Fatalities (thousands)", range = c(0, max(top_k$global_k)*1.25)),
  legend    = list(orientation = "h", x = 0.1, y = -0.2),
  margin    = list(b = 80),
  hovermode = "x unified"
)

7. References

References

  • AP News. (2017, December 21). Freedom from IS in Mosul costs lives of 9,000-plus civilians. https://www.apnews.com/article/6d94ba30348e4a25bf76e031b0212ef9

  • CBS News. (2017, December 20). AP says Mosul ISIS battle civilian death toll 10-times higher than US, Iraq acknowledge. https://www.cbsnews.com/news/ap-mosul-isis-civilian-death-toll-10-times-higher-us-iraq-acknowledge/

  • CNN. (2016, December 2). Mosul battle: Mounting death toll, urban warfare slow. https://www.cnn.com/2016/12/02/middleeast/iraq-mosul-battle-isis/index.html

  • CNN. (2016, December 3). Iraq disputes number killed in battle against ISIS. https://edition.cnn.com/2016/12/03/middleeast/iraq-mosul-battle-deaths/

  • Healy, K. (2018). Data visualization: A practical introduction. Princeton University Press.

  • Human Rights Watch. (2013, September 10). Attacks on Ghouta: Analysis of alleged use of chemical weapons in Syria. https://www.hrw.org/report/2013/09/10/attacks-ghouta/analysis-alleged-use-chemical-weapons-syria

  • Institute for Economics and Peace. (2023). Global Terrorism Index 2023: Measuring the impact of terrorism. https://www.economicsandpeace.org/global-terrorism-index/

  • R Core Team. (2023). R: A language and environment for statistical computing. R Foundation for Statistical Computing. https://www.R-project.org/

  • ReliefWeb. (n.d.). Mosul report 17Oct2016-10Jul2017, FINAL as of 30 October 2017. https://reliefweb.int/attachments/1319cb61-4d76-3cfa-bfd8-c075e91d0801/Mosul_report%2017Oct2016-10Jul201731%20October_2017.pdf

  • Telegrafi. (2016). Training of Russia’s anti-terrorist troops - like a real event (Video). https://telegrafi.com/en/the-training-of-the-anti-terrorist-troops-of-russias-as-a-real-video-event/

  • U.S. Department of Defense. (2019, October 27). U.S. forces kill ISIS founder, leader Baghdadi in Syria. https://www.defense.gov/news/news-stories/article/1999751/us-forces-kill-isis-founder-leader-baghdadi-in-syria/

  • Vox. (2017, December 20). The US spent months battling ISIS in Mosul. At least 9,000 civilians died. https://www.vox.com/world/2017/12/20/16800510/mosul-death-toll-isis-trump-war

  • Wickham, H., & Grolemund, G. (2017). R for data science: Import, tidy, transform, visualize, and model data. O’Reilly Media.