---
title: "Assignment 2"
subtitle: "Militarized Interstate Disputes in a Postmodern World"
author: "Xuesi Hou & Thomas Haase"
date: last-modified
date-format: long
 
execute:
  warning: false
  echo: false
  error: false  
format: 
  pdf: 
    toc: true
    geometry:
     - top=2cm
     - left=2cm
     - right=2cm
     - bottom=3cm
    fig-pos: 'h'
    fig-cap-location: bottom
    tbl-cap-location: bottom
    include-in-header:
    - text: |
        \usepackage{placeins}

number-sections: true

bibliography: citations.bib

editor_options: 
  chunk_output_type: console
---

---

<!-- The purpose of this assignment is to get some practice in practical selection of data, describing cohesion and community structure in networks: -->
<!-- - by calculating basic network properties, -->
<!-- - by performing visualizations of networks and degree distributions, -->
<!-- - by performing community detection algorithms, -->
<!-- - and by comparing and interpreting results of different algorithms. -->


```{r}
#| warning: false
#| echo: false
#| error: false
#| output: false

setwd("~/Github/sna_2")

library(tidyverse) # for easy data-wrangling
library(knitr) # convert outputs to markdown
library(gt) # nice tables (see https://themockup.blog/static/resources/gt-cookbook.html)

# read network libraries
library(igraph)    # basic graphlibrary
library(sna)       # useful functions
library(tidygraph) # tidy-style beautiful graphs
library(ggraph)    # tidy-style beautiful graphs
library(ggforce)   # for using the backbone layout

library(tidygraph) 
library(graphlayouts)
library(netrankr)  

library(countrycode)

library(rSpectral)
library(viridis)
```

```{r}
# read data
country_codes <- read.csv("data/COW-country-codes.csv") 

mida <- read.csv("data/MIDA 5.0.csv")
midb <- read.csv("data/MIDB 5.0.csv")
midi <- read.csv("data/MIDI 5.0.csv")
midip <- read.csv("data/MIDIP 5.0.csv")
```

```{r}
# combine both datasets
mid_all <- rbind(
  midb %>% 
    select(dispnum, ccode, styear, endyear, sidea, revtype1, revtype2, fatality, fatalpre),
  midip %>% 
    select(dispnum, ccode, styear, endyear, sidea, revtype1, revtype2, fatality, fatalpre)
  ) %>% 
  left_join(country_codes,by = c("ccode" = "CCode")) %>%
  rename(
    country       = StateNme,
    country_short = StateAbb
    ) %>% 
  distinct() # delete duplicate rows


# oh shit we have data from a lot of years. Uncomment and run the following line to take a look for yourself
#mid_all$styear %>% table() %>% barplot()


# filter relevant data
mid_all <- mid_all %>% 
  filter(endyear > 1949) # only include the postmodern world (germany was very split up before and occurs multiple times otherwise)

rm(mida, midb, midi, midip, country_codes)
```


```{r}
# create countryprojection

gc <- mid_all %>% 
  select(dispnum,country) %>%  # select disputes and countryy to create bipaartite graph
  table() %>%
  crossprod() %>% 
  as.matrix()

diag(gc) <- 0

gc <- graph_from_adjacency_matrix(
  gc,
  mode = "undirected",
  weighted = TRUE
)
```

```{r}
# Calculate country-level metrics
country_metrics <- mid_all %>%
  group_by(country) %>%
  mutate(fatalpre = ifelse(fatalpre < 1,0,fatalpre)) %>% 
  summarise(
    # Time involvement
    conflict_first = min(styear),
    conflict_last = max(endyear),
    conflict_timespan = conflict_last - conflict_first,
    
    # Initiative metrics
    total_conflicts = n(),
    initiated_conflicts = sum(sidea == 1),
    initiated_prop = initiated_conflicts / total_conflicts,
    
    # Fatality metrics
    fatalities_total = sum(fatalpre),
    fatalities_avg = mean(fatalpre),
    lethal_conflicts = sum(fatalities_total > 0),
    lethal_prop = lethal_conflicts / total_conflicts,
    
    # Aggression score (combining initiative and fatality)
    # Combined metric weighted as follows:
    #   50% from proportion of initiated conflicts
    #   30% from proportion of lethal conflicts
    #   20% from normalized average fatalities
    aggression_score = initiated_prop * 0.5 + lethal_prop * 0.3 + (fatalities_avg/max(fatalities_avg, na.rm = TRUE)) * 0.2
  )


# Add these metrics as vertex attributes to the graph
V(gc)$conflict_timespan <- country_metrics$conflict_timespan[match(V(gc)$name, country_metrics$country)]
V(gc)$initiated_prop    <- country_metrics$initiated_prop[match(V(gc)$name, country_metrics$country)]
V(gc)$fatalities_total  <- country_metrics$fatalities_total[match(V(gc)$name, country_metrics$country)]
V(gc)$fatalities_avg    <- country_metrics$fatalities_avg[match(V(gc)$name, country_metrics$country)]
V(gc)$lethal_prop       <- country_metrics$lethal_prop[match(V(gc)$name, country_metrics$country)]
V(gc)$aggression_score  <- country_metrics$aggression_score[match(V(gc)$name, country_metrics$country)]
```

```{r}
############################
# EXPLANATION OF VARIABLES #
############################
# The graph object contains the following information. The graph connects the countries which have been part of the same militarized incident. 

# WEIGHT (V(gc)$weight)
# The edges are weighted by the count of involvements in a certain incident with a country. A country can be involved in the same incident multiple times (e.g. sent drones at separate times during the same conflict) 

# TIMESPAN (V(gc)$conflict_timespan)
# The time span of a country's conflict involvement, calculated as the difference between their latest and earliest years they were part of any conflict. 

# PROPORTION OF INTITATED CONFLICTS (V(gc)$initiated_prop)
# The proportion of conflicts that a country initiated (where sidea = 1 in mid_all), ranging from 0 to 1
# A value of 0 means the country never initiated conflicts, while 1 means they initiated all their conflicts

# TOTAL FATALITIES (V(gc)$fatalities_total)
# The total number of fatalities across all conflicts a country was involved in
# This provides a measure of the overall deadly impact of a country's conflicts

# AVERAGE FATALITIES (V(gc)$fatalities_avg)
# The mean number of fatalities per conflict for each country
# This normalizes the fatality count by the number of conflicts, allowing comparison between countries with different numbers of conflicts

# LETHAL PROPORTION (V(gc)$lethal_prop)
# The proportion of a country's conflicts that resulted in at least one fatality (fatality > 0)
# Ranges from 0 to 1, where 0 means no lethal conflicts and 1 means all conflicts were lethal

# AGGRESSION SCORE (V(gc)$aggression_score)
# A composite measure combining initiative and lethality metrics with the following weights:
# - 50% from proportion of initiated conflicts
# - 30% from proportion of lethal conflicts
# - 20% from normalized average fatalities
# Higher scores indicate more aggressive conflict behavior through both initiation and intensity
```

```{r}
V(gc)$name_short <- mid_all$country_short[match(V(gc)$name, mid_all$country)]

V(gc)$continent <- countrycode(
  sourcevar=V(gc)$name,
  origin="country.name",
  destination = "continent"
  ) %>% 
  as.factor() %>% 
  fct_na_value_to_level("Dissolved countries")
```

\newpage
# Task 1
> Formulate theoretical arguments and expectations about interstate relations. Think in network terms. Select the appropriate part of the data for analysis.

## Introduction to the Data

The selected dataset is the [Military Interstate Disputes V5.0](https://correlatesofwar.org/data-sets/mids/) dataset of the _correlates of war_ project. It contains information about "all instances of when one state threatened, displayed, or used force against another."[@palmer2022]. Each incident contains a description and is linked to all countries including who initiated the conflict, the start and end time, casualties and most importantly the countries connected to the incidents. 

This bipartite graph of countries connected to incidents is projected to a network where only countries are connected to each other based on how many incidents they shared/were part of.
We filter the data only for conflicts happening in the post modern world after 1949.

## Expectations
It is not far fetched to theorize that geographical location is playing a major role in sharing military incidents, because those borders are most probable not only the result of such disputes but being a neighboring country also can pull a country inside of a conflict that it was originally no part of. 

Since the data was filtered to include only the years 1949 - 2014, the analysis is expected to reflect the most important geopolitical conflicts of this era.
The major terms under which many incidents happened were the cold war era (1949-1991) and the post-cold war era. During the cold war the US and Russia fought a series of proxy wars like:

- Korean War (1950-1953)
- Vietnam War (1955-1975)
- Cuban Missile Crisis (1962)
- Arab-Israeli Wars
  - Six-Day War (1967), Yom Kippur War (1973)
- Soviet-Afghan War (1979-1989)
- Iran-Iraq War (1980-1988)

The post-cold war era (1991-2014) is characterized by mostly wars in africa, the middle east and eastern europe:

- Gulf War (1990-1991)
- Yugoslav Wars (1991-2001)
- First (1994-1996) and Second (1999-2009) Chechen War
- Congo Wars (1996-2003)
- Afghanistan War (2001-2014)
- Iraq War (2003-2011)
- Arab Spring conflicts (2010-2014)
- Russo-Georgian War (2008)
- Syrian Civil War (2011-ongoing)
- Crimean Crisis (2014-ongoing)

Because of their hegemonial position in the world order the US, Russia and Europe probably have a very high degree (were part of many incidents). Many of the listed wars are local with the involvement of a few larger nations as perpetuators or mediators in war/military disputes. We expect the data to represent this relationship. 


\newpage
\FloatBarrier
# Task 2
> On the selected data, make a table that contains descriptive statistics for the network and for the distribution of key node-level variables. Please mention the historical period covered, the nature of tie(s), the number of nodes and ties, average degree, density, the standard deviation of degrees (or outdegrees and of indegrees if network is directed), and average path length. Identify the number of isolates if there are any. Please check if the network is a single component. Which node has the highest degree, and which has the highest betweenness centrality? What do these measures represent in terms of the specific type of relations and data you have selected?

The analysis transforms a two-mode network (bipartite graph) into a one-mode network through projection. The original network connects two distinct types of nodes: countries and incidents. In the projected network, only countries remain as nodes, and they become connected when they were involved in the same incidents. The strength of connection between any two countries is determined by the number of shared incidents between them.
The analysis focuses exclusively on the contemporary post-World War II era, specifically from 1949 onwards until 2014, the last year recorded in the dataset. 

<!-- number of nodes and ties -->
<!-- average degree -->
<!-- density -->
<!-- standard deviation of degrees -->
<!-- average path length -->
<!-- Number of Isolates if there are any-->
<!-- how many components -->
<!-- Node with highest degree -->

<!-- Node with highest betweenness centrality -->

```{r}
#| fig.align: center
#| layout: "[[1,1], [1]]"
#| fig-width: 4
#| fig-height: 3


########################
# Descriptive Statistics
########################

nodecount <- V(gc) %>% length() %>% as.character()
tiecount  <- E(gc) %>% length() %>% as.character()
density   <- edge_density(gc) %>% round(2) %>% as.character()
# calculate indegree int he format: "average ± standard deviation"
degree <- str_c(
  gc %>% # calculate average indegree
    igraph::degree(mode = "total") %>%
    mean() %>%
    round(1),
  " ± ", # ... plus-minus the ...
  gc %>% # ...standard deviation of indegree
    igraph::degree(mode = "total") %>%
    sd() %>%
    round(1)
)
avg_path_length <- gc %>% mean_distance() %>% round(2) %>% as.character()
# there are no isolates
# gc %>% as_adjacency_matrix() %>% as.matrix %>% isolates()
component_count <- igraph::components(gc)$no %>% as.character()
component_size  <- igraph::components(gc)$csize %>% as.character()


tibble::tribble(
     ~"Parameter",          ~"Value (AVG ± SD)", 
     "Node Count",          nodecount,
     "Tie Count",           tiecount,
     "Degree",              degree,
     "Average Path Length", avg_path_length,
     "Component Count",     component_count,
     "Component Size",      component_size
     ) %>%
     gt::gt() %>%   
     tab_header(
       title = "Descriptive Summarystatistics",
       subtitle = "Military Interstate Disputes"
       ) %>% 
     tab_footnote(
       footnote = "Countries are connected by being part of the same dispute and weighted with the count of occuring in shared disputes.",
       locations = cells_title(groups = "subtitle")
     ) %>% 
    tab_style(
      style = cell_fill(color = "#d9f7ff"),
      locations = cells_body(columns = Parameter)
    ) %>% 
    tab_style(
      style = cell_fill(color = "#9de7fa"),
      locations = cells_column_labels(columns = Parameter)
    ) %>%
    tab_style(
      style = cell_text(weight = "bold"),
      locations = cells_title(groups = "title")
    )


##############################
# GRAPH OF DEGREE DISTRIBUTION
##############################
gc %>% 
     igraph::degree(mode="total") %>%
     as.tibble() %>%  
  ggplot(aes(x = value)) +
     geom_bar(fill = "#006F91") +
     labs(title = "Degree Distribution",
          subtitle = "",
          x = "Degree",
          y = "Count",
          caption = "Data from COW Military Interstate Disputes V5.0") +
     scale_x_continuous(limits = c(-1,110), breaks = seq(0,110,10))+
     scale_y_continuous(limits = c(0,20)) +
     theme_minimal()




######################
# Top Centrality Nodes
######################

# Calculate Degree
`Degree Score` <- gc %>% 
  igraph::degree(mode = "total") %>% 
  sort(decreasing = TRUE) %>% 
  head(5) 

`Top Degree` <- mid_all$country_short[match(names(`Degree Score`), mid_all$country)]


# Calculate Betweenness
`Betweenness Score` <- gc %>% 
  igraph::betweenness(directed = TRUE,
                      weights = E(gc)$weight,
                      normalized = TRUE) %>%
  sort(decreasing = TRUE) %>% 
  round(2) %>% 
  head(5)

`Top Betweenness` <- mid_all$country_short[match(names(`Betweenness Score`), mid_all$country)]


# Calculate Eigenvectorcentrality
`Eigenvector Score` <- eigen_centrality(
    gc,
    directed = FALSE,
    scale = TRUE,
    weights = E(gc)$weight,
    options = arpack_defaults
  )$vector %>% 
  sort(decreasing = TRUE) %>%
  round(2) %>% 
  head(5) 

`Top Eigenvector` <- mid_all$country_short[match(names(`Eigenvector Score`), mid_all$country)]



tibble(`Top Degree`,`Degree Score`,
       `Top Betweenness`,`Betweenness Score`,
       `Top Eigenvector`, `Eigenvector Score`) %>% 
  gt::gt() %>% 
  tab_header(title = "Top Countries by Centrality Measures") %>% 
  tab_footnote(
    footnote = "Countries are connected by being part of the same dispute and weighted with the count of occuring in shared disputes.",
    locations = cells_title(groups = "title")
  ) %>% 
  tab_footnote(
    footnote = "Scores are calculated including weights",
    locations = cells_column_labels(columns = c(`Degree Score`,
                                                `Betweenness Score`, 
                                                `Eigenvector Score`)
                                    )
  ) %>% 
  tab_style(
    style = cell_fill(color = "#d9f7ff"),
    locations = cells_body(columns = c(`Top Degree`, 
                                       `Top Betweenness`, 
                                       `Top Eigenvector`)
                           )
  ) %>% 
  tab_style(
    style = cell_fill(color = "#9de7fa"),
    locations = cells_column_labels(columns = c(`Top Degree`, 
                                                `Top Betweenness`,
                                                `Top Eigenvector`)
                                    )
  ) %>%
  tab_style(
    style = cell_text(weight = "bold"),
    locations = cells_title(groups = "title")
  )
```
\FloatBarrier
The table with descriptive summarystatistics describes the network having 181 nodes, including most existing countries in the postmodern world (since 1949). The network has 1964 ties, so at a network level without considering nodedegree we would expect each node to have $\frac{1964}{181} \sim 10$ connections. So on average a node is involved in military disputes with $\sim 10$ other countries.

The average path length being 21.7 shows that on average a country is connected to another country via ~20 disputes on average. What is striking is the very large standard deviation of degrees. The Standard deviation of the degree measure is larger than the average itself, indicating the existance of massive superhubs. This observation is backed up by the plog of degree distributions showing a very long tail. The plot of degree distributions reveals many countries having degreecount of less than 20, which means most countries are part less than 20 incidents. There is a smaller spike at degreecount 50, which means that there seems to be a set of countries involved in many more incidents. These could also be the result of some incidents involving the same countries many times. One country is a big outlier with over 100 degrees. 

The average path length of the network is 6.9 and therefore very short. This implies the existance of shortcuts, similar to the small world network [@watts1999a]. This could mean that there are military incidents connecting countries from different hubs. 

The network consists of only one comoponent due to only including countries that are actually linked by military interstate desputes. 


The table "Top Countries by Centrality Measures" presents centrality measures for countries involved in military interstate disputes.
The United States leads with the highest degree score of 108, followed by United Kingdom (92), France (91), Russia (84), and the Netherlands (77). This indicates that the US was involved in the most shared military incidents during this period, reflecting its global military presence and engagement in numerous conflicts.

The betweenness centrality scores show the US again leading (0.16), followed by United Kingdom (0.10), France (0.10), Iran (0.08), and Latvia (0.07). These scores suggest these countries often served as critical intermediaries in the conflict network, potentially playing important roles in regional disputes or international interventions.

Azerbaijan leads with a score of 1.00, followed by Armenia (1.00), Russia (1.00), Turkey (0.06), and the US (0.05). The high eigenvector scores for Azerbaijan, Armenia, and Russia suggest these countries were connected to other highly central actors in the network, particularly in regional conflicts.

This data aligns with historical events during this period. The US's high degree and betweenness scores reflect its involvement in major conflicts like the Korean War, Vietnam War, and Gulf Wars. The prominent positions of United Kingdom and Russia align with Cold War dynamics and post-Soviet conflicts. The high eigenvector scores for Caucasus region countries (Azerbaijan, Armenia) and Turkey indicate the significance of regional conflicts in that area.
The presence of both Western powers (US, France) and Eastern powers (Russia) at the top of these rankings reflects the bipolar nature of the Cold War period and its aftermath, demonstrating how these powers were central to global military disputes during this era.

\FloatBarrier
```{r}
#| fig.align: center
#| layout-ncol: 2
#| fig-width: 4
#| fig-height: 3

##############################################
# GRAPH OF BETWEENNESS CENTRALITY DISTRIBUTION
##############################################
gc %>% 
  igraph::betweenness(directed = TRUE,
                      weights = E(gc)$weight,
                      normalized = TRUE) %>%
  as.tibble() %>%  
  ggplot(aes(x = value)) +
  geom_histogram(binwidth = 0.005, fill = "#006F91", color = "white") +
  labs(
    title = "Histogramm of Betweenness Centrality",
    x = "Value",
    y = "Count",
    caption = "Data from COW Military Interstate Disputes V5.0"
  ) +
  theme_minimal()

##############################################
# GRAPH OF EIGENVECTOR CENTRALITY DISTRIBUTION
##############################################
  eigen_centrality(
    gc,
    directed = FALSE,
    scale = TRUE,
    weights = E(gc)$weight,
    options = arpack_defaults
  )$vector %>%
  as.tibble() %>%  
  ggplot(aes(x = value)) +
  geom_histogram(binwidth = 0.05, fill = "#006F91", color = "white") +
  labs(
    title = "Histogramm of Eigenvector Centrality",
    x = "Value",
    y = "Count",
    caption = "Data from COW Military Interstate Disputes V5.0"
  ) +
  theme_minimal()
```
\FloatBarrier


The Betweenness Centrality Histogram shows a highly skewed distribution with the vast majority of countries having very low betweenness centrality. There's a steep drop-off after the first bar, indicating that very few countries serve as important "bridges" in the network. Only a handful of countries (as we saw in the previous table - like USA, United Kingdom, France) have higher betweenness scores around 0.10-0.15. This suggests that most countries are involved in regional or localized conflicts, while a small number of powerful nations act as intermediaries across different conflict zones

The Eigenvector Centrality Histogram shows an even more extreme concentration, with almost all countries having very low eigenvector centrality scores of 0. There's a small group of countries with very high scores (around 1.0), which we know from the table includes Azerbaijan, Armenia, and Russia. The stark binary nature of this distribution (mostly either very low or very high) suggests a clear hierarchy in the conflict network, there seem to be some disputes connecting very "popular" countries (countries involved in many disputes) to Azerbaijan, Armenia and Russia. 

Together, these distributions reveal a highly centralized network structure where a small number of countries play disproportionately important roles in global military disputes, while the majority of nations have more limited involvement. This aligns with what we might expect given the global power dynamics during the Cold War and post-Cold War periods, where superpowers and regional powers dominated international military engagements.

\FloatBarrier


```{r}
###################################
# GRAPH OF TOP FATALITIES COUNTRIES
###################################

`Top Fatality Score`<- cbind(
  V(gc)$name,
  V(gc)$fatalities_total
) %>% 
  as.data.frame() %>% 
  rename(
    Country = V1,
    `Fatality Count` = V2
  ) %>% 
  mutate(`Fatality Count` = as.numeric(`Fatality Count`)) %>%
  filter(`Fatality Count` > 0) %>% 
  drop_na(`Fatality Count`) %>%
  mutate(`Fatality Count` = abs(`Fatality Count`)) %>% 
  arrange(desc(`Fatality Count`)) %>% 
  mutate(`Fatality Count` = round(`Fatality Count`, 2)) %>% 
  head(5)



tibble(`Top Fatality Score`) %>% 
  gt::gt() %>% 
  tab_header(title = "Top Countries by Fatalities Count") %>% 
  tab_style(
    style = cell_fill(color = "#d9f7ff"),
    locations = cells_body(columns = Country)
  ) %>% 
  tab_style(
    style = cell_fill(color = "#9de7fa"),
    locations = cells_column_labels(columns = Country)
  ) %>%
  tab_style(
    style = cell_text(weight = "bold"),
    locations = cells_title(groups = "title")
  )
```
\FloatBarrier

# Rewrite Interpretation

The table about the Countries with most fatalities in the dataset is best interpreted using the description of the disputes of the certain countries. 

Iraq's count of 7,025 fatalities stands markedly higher than other countries, indicating its involvement in major conflicts including the Iran-Iraq War and Iraq War. Pakistan and India's figures (950 and 562 fatalities respectively) stem largely from their Kashmir territorial dispute, while Azerbaijan and Armenia's numbers (684 and 434) reflect intense regional conflicts in the Caucasus following the Soviet Union's dissolution. 


```{r}
# mid_all %>% 
#   filter(country == "China") %>% 
#   filter(fatalpre > 0)
```


\FloatBarrier

```{r}
#| fig.align: center
#| layout: "[[47.5,-5,47.5],[100]]"
#| fig-width: 4
#| fig-height: 3

##############################
# GRAPH OF INITIATED CONFLICTS
##############################
V(gc)$initiated_prop %>%
  as_tibble() %>%
  ggplot(aes(x = value, fill = after_stat(count))) +
  geom_histogram(binwidth = 0.05, color = "white") +
  scale_fill_gradient(low = "#B3D4E0", high = "#006F91") +
  #scale_x_continuous(breaks = seq(0, 65, 5)) +
  labs(
    title = "Initiated Conflicts on Countrylevel",
    subtitle = 'Proportion of Conflicts on "Attacking"" Position',
    x = "Proportion of Conflicts",
    y = "Number of Countries",
    caption = "Data from COW Military Interstate Disputes V5.0"
  ) +
  theme_minimal() +
  theme(
    legend.position = "none"
  )

###########################
# GRAPH OF TOTAL FATALITIES
###########################
V(gc)$fatalities_avg %>%
  abs() %>% 
  as_tibble() %>%
  mutate(value = value + 0.0001) %>%  # Add 1 to handle zeros
  ggplot(aes(x = value, fill = after_stat(count))) +
  geom_histogram(binwidth = 0.25, color = "white") +
  scale_fill_gradient(low = "#B3D4E0", high = "#006F91") +
  scale_x_log10(labels = scales::comma) +
  labs(
    title = "Average Fatalities of Countries",
    subtitle = 'Average of fatalities countries had in all conflicts between 1949 - 2014',
    x = "Average Fatalities (log scale)",
    y = "Number of Countries",
    caption = "Data from COW Military Interstate Disputes V5.0"
  ) +
  theme_minimal() +
  theme(
    legend.position = "none"
  )



############################
# GRAPH OF CONFLICT TIMESPAN
############################
V(gc)$conflict_timespan %>%
  as_tibble() %>%
  ggplot(aes(x = value, fill = after_stat(count))) +
  geom_bar(color = "white") +
  scale_fill_gradient(low = "#B3D4E0", high = "#006F91") +
  scale_x_continuous(breaks = seq(0, 65, 5)) +
  labs(
    title = "Temporal Span of Conflicts on Countrylevel",
    subtitle = "Time between first and last year of involvement of a country",
    x = "Years Between First and Last Conflict",
    y = "Number of Countries",
    caption = "Data from COW Military Interstate Disputes V5.0"
  ) +
  theme_minimal() +
  theme(
    legend.position = "none"
  )


```

The initiated conflicts histogram reveals that countries typically initiated between 25-75% of their military engagements, with a notable peak around 50%. This distribution implies that most nations alternated between initiating and responding to military disputes, rather than consistently assuming either role.

The fatalities histogram demonstrates a right-skewed distribution, with most countries experiencing relatively low average casualties while a small number of conflicts resulted in significantly higher fatality rates. This pattern aligns with the presence of both limited military engagements and more intensive warfare during the studied period.

The temporal span distribution indicates considerable variation in conflict duration, with most disputes resolving within 20 years while some extended conflicts persisted for up to 40 years. This bimodal distribution suggests the coexistence of both acute military engagements and protracted disputes during this period.

The analysis reveals three main patterns in military conflicts: First, most nations showed balanced engagement, initiating about half of their disputes. Second, while most conflicts had relatively low casualties, a few resulted in significantly higher fatalities. Finally, conflict durations varied widely, with most lasting under 20 years but some extending up to 40 years.


\newpage
\FloatBarrier
# Task 3
> Visualize the network. Vary degree color and size according to key node attributes. Try to pick a node attribute that relates to an important characteristic (e.g., power, GDP per capita).



```{r}
#| fig.align: center
#| fig-width: 10
#| fig-height: 7



gc %>% 
  # igraph as tidygraph
  as_tbl_graph() %>% 
  # activate nodes for nodemanipulation
  activate("nodes") %>% 
  # add centralitymeasures
  mutate(Eigenvector = eigen_centrality(gc,
                                   directed = TRUE,
                                   scale = TRUE,
                                   weights = E(gc)$weight)$vector,
         Betweenness = igraph::betweenness(gc,
                                           directed = TRUE,
                                           weights = E(gc)$weight,
                                           normalized = T),
      Degree = igraph::degree(gc, mode="all")) %>% 
  mutate(
    fatalities_total = abs(fatalities_total),
    fatalities_avg   = abs(fatalities_avg),
  ) %>% 
  rename(
    `Timespan between first and last conflict` = conflict_timespan,  
    `Proportion of Initiated Disputes` = initiated_prop,
    `Total Fatalities` = fatalities_total,
    `Average Fatalities` = fatalities_avg,
    `Proportion of lethal Disputes` = lethal_prop,
    `Aggression Score` = aggression_score,
    `Short Name` = name_short,
    Name = name,
    Continent = continent
  ) %>%  
  # start plot
#ggraph("backbone", keep = 0.8) + 
ggraph(
  layout = "centrality",
  #cent = graph.strength(gc),
  cent = igraph::degree(gc)#,
  #group = V(gc)$Continent
  ) +
  geom_edge_bundle_path(
    tension = 0.75,
    width = 0.08,
    edge_color = "darkgray") +
  geom_node_point(
      aes(size  = Degree,
          colour  = Continent),
      shape = 19, show.legend = TRUE
  ) +
  # geom_node_text(aes(label = `Name`),
  #                size = 2.2,
  #                fontface = "bold",
  #                color = "black") +
  shadowtext::geom_shadowtext(aes(x, y, label = `Name`), 
                              color = "black", size = 2.2, 
                              bg.colour = "white", fontface = "bold",
                              bg.r=0.05) +
  scale_size(range = c(3,9)) +
  theme_void() +
  labs(
    title = "Countries connected by shared Military Interstate Disputes",
    subtitle = "By Continents",
    caption = "Data from COW Military Interstate Disputes V5.0\n Layout: Degreebased Centrality"
  ) +
  theme(plot.title = element_text(face = "bold", size = 16),
        plot.subtitle = element_text(size = 15),
        legend.position = "right",
        legend.text = element_text(size = 10),
        legend.title = element_text(size = 11, face = "bold"))
```


The network shows European nations are densely connected, particularly in Eastern Europe, indicating frequent military interactions within the region. This pattern likely reflects both Cold War tensions and post-Soviet conflicts. Asian countries show strong regional clustering, with notable connections centered around key regional powers and territorial disputes.
African nations appear more dispersed throughout the network, suggesting more localized conflicts rather than continent-wide military engagements. The Americas display relatively fewer interconnections, with most countries maintaining lower degree centrality except for the United States. The United States dominate the network with their high degree being part of most conflicts.
The presence of dissolved countries adds an important historical dimension, particularly in Eastern Europe, highlighting how geopolitical restructuring influenced military dispute patterns. Especially Yugoslavia being in the central cluster of european states highlights the power of the now not anymore existing state.

Especially interesting is the representation of large international conflicts with a lot of parties by the bundled edges. Especially visible is this phenomenon with Iraq, Iran, Pakistan and Isreal. 


\newpage
\FloatBarrier
# Task 4 {#sec-4}
> Implement and compare the results (community compositions, their size) of TWO different community detection algorithms to find communities (e.g., Girvan-Newman, Louvain, walktrap, cohesive blocks, Leiden). Please take into account that most of these methods can use undirected graphs only, others (such as Girvan-Newman) might work with weighted graphs. Before carrying out this task, simplify the data if necessary. Create a plot where nodes are either colored based on detected community membership, or you can circulate the groups with some color in the background.


<!-- 

- 2 community detection algorithms

- create a plot where nodes are either colored based on detected community membership, or you can circulate the groups with some color in the background.


- compare results

-->

```{r}
#| fig.align: center
#| layout-ncol: 1
#| fig-width: 10
#| fig-height: 7

bb <- layout_as_backbone(gc, keep = 0.8)
E(gc)$col <- F
E(gc)$col[bb$backbone] <- T

gc %>%
  # igraph as tidygraph
  as_tbl_graph() %>%
  # activate nodes for nodemanipulation
  activate("nodes") %>%
  # add centralitymeasures
  mutate(Eigenvector = eigen_centrality(gc,
                                   directed = TRUE,
                                   scale = TRUE,
                                   weights = E(gc)$weight)$vector,
         Betweenness = igraph::betweenness(gc,
                                           directed = TRUE,
                                           weights = E(gc)$weight,
                                           normalized = T),
      Degree = igraph::degree(gc, mode="all")) %>%
  mutate(
    fatalities_total = abs(fatalities_total),
    fatalities_avg   = abs(fatalities_avg),
  ) %>%
  rename(
    `Timespan between first and last conflict` = conflict_timespan,
    `Proportion of Initiated Disputes` = initiated_prop,
    `Total Fatalities` = fatalities_total,
    `Average Fatalities` = fatalities_avg,
    `Proportion of lethal Disputes` = lethal_prop,
    `Aggression Score` = aggression_score,
    `Short Name` = name_short,
    Name = name,
    Continent = continent
  ) %>%
  mutate(Community = as.factor(group_louvain())) %>% # communitydetection
#ggraph(layout = "manual",x = bb$xy[, 1],y = bb$xy[, 2]) +
ggraph(
  layout = "centrality", 
  #cent = graph.strength(gc),
  cent = igraph::degree(gc)#,
  #group = V(gc)$Continent
  ) +
  geom_edge_bundle_path(
    tension = 0.75,
    width = 0.08,
    edge_color = "darkgray") +
  geom_node_point(
      aes(colour  = Community),
      shape = 19, show.legend = TRUE, size = 5) +
  # geom_node_text(aes(label = `Short Name`),size = 2,
  #                fontface = "bold",color = "black") +
  shadowtext::geom_shadowtext(aes(x, y, label = `Name`), 
                            color = "black", size = 2.2, 
                            bg.colour = "white", fontface = "bold",
                            bg.r=0.05) +
  theme_void() +
  scale_color_viridis(discrete =TRUE, option="turbo") +
  scale_fill_viridis(discrete = TRUE, option="turbo") +
  labs(
    title = "Community Detection: Louvain",
    subtitle = "Countries connected by shared Military Interstate Disputes",
    caption = "Data from COW Military Interstate Disputes V5.0\nAlgorithm from Blondel et al. (2008)\n Layout: Degreebased Centrality") +
  theme(plot.title = element_text(face = "bold", size = 16),
        plot.subtitle = element_text(size = 15),
        legend.position = "right",
        legend.text = element_text(size = 10),
        legend.title = element_text(size = 11, face = "bold")
        )









gc %>% 
  # igraph as tidygraph
  as_tbl_graph() %>% 
  # activate nodes for nodemanipulation
  activate("nodes") %>% 
  # add centralitymeasures
  mutate(Eigenvector = eigen_centrality(gc,
                                   directed = TRUE,
                                   scale = TRUE,
                                   weights = E(gc)$weight)$vector,
         Betweenness = igraph::betweenness(gc,
                                           directed = TRUE,
                                           weights = E(gc)$weight,
                                           normalized = T),
      Degree = igraph::degree(gc, mode="all")) %>% 
  mutate(
    fatalities_total = abs(fatalities_total),
    fatalities_avg   = abs(fatalities_avg),
  ) %>% 
  rename(
    `Timespan between first and last conflict` = conflict_timespan,  
    `Proportion of Initiated Disputes` = initiated_prop,
    `Total Fatalities` = fatalities_total,
    `Average Fatalities` = fatalities_avg,
    `Proportion of lethal Disputes` = lethal_prop,
    `Aggression Score` = aggression_score,
    `Short Name` = name_short,
    Name = name,
    Continent = continent
  ) %>%  
  mutate(Community = as.factor(
    spectral_igraph_membership(gc, Cn_min = 2)$membership)
    ) %>%
  #mutate(Community = as.factor(group_leading_eigen(weights = E(gc)$weight))) %>% 
#ggraph(layout = "manual",x = bb$xy[, 1],y = bb$xy[, 2]) +
ggraph(
  layout = "centrality", 
  #cent = graph.strength(gc),
  cent = igraph::degree(gc)#,
  #group = V(gc)$Continent
  ) +
  geom_edge_bundle_path(
    tension = 0.75,
    width = 0.08,
    edge_color = "darkgray") +
  geom_node_point(
      aes(
        size  = Betweenness,
        colour  = Community
        ),
      shape = 19, show.legend = TRUE, size = 5) +
  # geom_node_text(aes(label = `Short Name`),size = 2,
  #                fontface = "bold",color = "black") +
  shadowtext::geom_shadowtext(aes(x, y, label = `Name`), 
                            color = "black", size = 2.2, 
                            bg.colour = "white", fontface = "bold",
                            bg.r=0.05) +
  scale_color_viridis(discrete =TRUE, option="turbo") +
  scale_fill_viridis(discrete = TRUE, option="turbo") +
  theme_void() +
  labs(
    title = "Community Detection: Spectrality based Leading-Eigenvector",
    subtitle = "Countries connected by shared Military Interstate Disputes",
    caption = "Data from COW Military Interstate Disputes V5.0\nAlgorithm from Newman (2006)\n Layout: Degreebased Centrality") +
  theme(plot.title = element_text(face = "bold", size = 16),
        plot.subtitle = element_text(size = 15),
        legend.position = "right",
        legend.text = element_text(size = 10),
        legend.title = element_text(size = 11, face = "bold")
        )

```



The Louvain algorithm visualization identifies five communities. They represent mainly regional grouping from the continents, but some countries in the center regions now are part of the outer regional communities. For example the France is now part of a cluster with some African countries and countries from the middle east. Some Western Asian and Middle eastern countries are now part of the European cluster. The Louvainclustering therefore revealed partly geographical distinctions in Asia, aswell as hegemonial and power-related structures (regarding the middle east), aswell as highlighting some major conflict involvements (Frances position).

The Spectrality based Leading-Eigenvector Clustering revealed 8 communities. The communities are very similar to the results of the Louvain clustering. One difference between the clustering algorithms would be that the African countries are now differentiated between those connected to military disputes with France, while central Asia is also their own community (Tajikistan, Mongolia, Uzbekistan,...).


```{r}
#| include: false
detect_communities <- function(graph, Cn_min) {
  membership <- cluster_leading_eigen(graph)$membership
  comm_sizes <- table(membership)
  valid_communities <- sum(comm_sizes >= Cn_min)
  return(valid_communities)
}

# Generate a random graph
set.seed(42)
n_nodes <- 100
p_edge <- 0.05

# Run simulation for different Cn_min values
Cn_min_values <- seq(0, 100, by = 1)
results <- sapply(Cn_min_values, function(Cn) detect_communities(gc, Cn))

results %>% plot(type="l")

diff(results)
```


\newpage
\FloatBarrier
# Task 5
> Make meaningful comparisons between the results of community detection algorithms. Summarize the differences and similarities and try to explain these. Please refer to the relevant literature describing the logic of these algorithms if necessary.

As mentioned in @sec-4 both algorithms indicate geographical aswell as powerrelated structures of the world order. Some conflicts and colonial relations are large enough to push through this geographical pattern to form and influence the grouping of communities.


## The Louvain Algorithm
<!-- How the algorithm works -->
The Louvain Algorithm is a greedy technique for clustering a network into non-overlapping communities [@blondel2008].
At first, each node is their own community. Then the nodes are clustered locally via modularityoptimization. After reaching the first local maxima the algorithm proceeds with phase 2 which aggregates the communities into blocks including elements of a weighted graph, with edge count between them. Then clustering is repeated. 

### Intuition
<!-- What does it do with our data? -->
In case of the used data countries are connected by shared military disputes. Two countries are part of the same community if they shared considerably more disputes with each other than with other countries (=modularity-optimization). These local clusters of common friends and enemies are used in the second step to optimize the clusters even further. By this we reach clusters of countries who frequently interact in the context of military incidents.



## Spectrality based Leading-Eigenvector Algorithm
<!-- How the algorithm works -->
@newman2006 developes a clustering algorithm which is based on the usage of a modularity matrix allowing a leading-eigenvector based optimization elevating spectral techniques [@newman2006]. 

"The complete iterative algorithm comprises of two steps. In the first step, the network is expressed in terms of its leading eigenvalue and eigenvector and recursively partition into two communities. Partitioning occurs if the maximum positive eigenvalue is greater than the tolerance threshold for the current partition, and if it results in a positive contribution to the modularity.
Given an initial separation using the leading eigen step, the function then continues to maximise for the change in Modularity using a fine-tuning step [...]. The first stage is to find the node which, when moved from one community to another, gives the maximum change in modularity. This node’s community is then fixed and [the process is repeated] until all nodes have been moved. The whole process is repeated from this new state until the change in the Modularity, between the new and old state, is less than the predefined tolerance."[@mclean2022]


### Intuition
<!-- What does it do with our data? -->
The modularity matrix contains elements $B_{vw} = A_{vw} - \frac{k_v k_w}{2m}$ representing the difference between the expected and observed tie for each observed edge [@newman2006]. In terms of our network those values are the difference between the countries we expect to share military incidents and the countries that actually share military incidents. This depicts the notion of a country to connect to another country via shared military incidents. 

The eigenvector of this matrix describes the orientation of distortion that countries notions to connect to each other through shared military disputes in the space of all countries. The eigenvalue describes the scale into the direction of said distortion. The exact same procedure is used for Principal Component Analysis and this similarity is even mentioned by @newman2006. 

A community can then be expressed as the orthogonal vector of the vector of edgecombinations which is similar to the result of PCAs. This orthogonal vector then cuts the space, which describes the deviation from expected and observed edges, in 2. This cut is chosen so it optimizes modularity. In terms of our dataset: The communityvector should in theory describe the incidents which were part of the bipartite graph before we projected the bipartite graph to a country network. Following this, the orthogonal vector of the incident-vector cuts modularitymatrix $B_vw$ in 2 large clusters optimizing modularity so that the result are two super-groups of incidents splitting the country-projection with the optimal modularity. This is splitting/"PCA-on-graphs" is repeated until a certain tolerance threshhold is reached. 

## Comparison
In conclusion both algorithms in theory should be able to retrieve the most important information of incidents which got lost during the projection of the bipartite graph. They also implicitly depict the underlying structures generating the edges of being part of the same international military disputes. These underlying structures seem to be a structure of international hegemony still reproducing structures generated by the colonial era aswell as geographical location and sharing borders.




\FloatBarrier
\newpage
# Bibliography