Cât durează războaiele, în medie? Dacă un război precum cel care se desfășoară în prezent în Iran a durat până acum 74 de zile, cât timp ne așteptăm să dureze în total? Din tot felul de motive, mințile interesate sunt interesate. Din fericire, există câteva seturi de date foarte bine îngrijite, inclusiv Corelates of War, care facilitează răspunsul la aceste întrebări.
Se aplică o avertizare la toate acestea că nu sunt un istoric militar, doar un amator interesat. Sunt foarte deschis să mi se sublinieze greșeli de interpretare sau de metodă.
Distribuția duratelor războaielor
Datele Corelates of War ne permit să vedem, de exemplu, că aceasta este distribuția (pe o scară logaritmică) a duratelor războaielor post-Napoleon:
Puteți vedea că am comparat aceasta cu o distribuție log-normală și am descoperit că nu are cozi atât de grase ca asta. Dar e ok, nu sunt prea îngrijorat de forma precisă, pentru că mai târziu voi folosi metode empirice destul de simple.
Aceste date sunt doar pentru războaiele interstatale, care sunt în contrast cu cele intra-statale (de exemplu, războaie civile) și extra-statale (de exemplu, cu actori nestatali externi). Deoarece sunt interesat de o populație de referință cu care să compare războiul actual SUA-Israel-Iran, este populația interstatală pe care o vreau.
Durata medie a unui război este de 139 de zile, iar media este de 408 zile.
Războiul de patru zile din setul de date este așa-numitul „Război al fotbalului” din 1969 între Honduras și El Salvador. Războiul de 3.734 de zile a fost mult mai cunoscutul „Faza a II-a a Războiului din Vietnam”, care a implicat SUA, Australia, Vietnam, Cambodgia și alții.
Iată codul pentru a importa datele din proiectul Corelates of War și pentru a trage primul diagramă de densitate:
library(tidyverse)
library(lubridate)
library(janitor)
library(glue)
library(ggrepel)
library(scales)
# https://correlatesofwar.org/data-sets/cow-war/
#----- import interstate war data----------------------
interstate <- read_csv("https://correlatesofwar.org/wp-content/uploads/Inter-StateWarData_v4.0.csv") |>
clean_names() |>
mutate(start_date = as.Date(sprintf("%04d-%02d-%02d", start_year1, start_month1, start_day1)),
end_date = as.Date(sprintf("%04d-%02d-%02d", end_year1, end_month1, end_day1)))
interstate_wars <- interstate |>
group_by(war_num, war_name) |>
summarise(earliest_start= min(start_date),
latest_end = max(end_date),
bat_death = sum(bat_death)) |>
mutate(duration = as.numeric(latest_end - earliest_start),
start_year = year(earliest_start)) |>
ungroup()
# what years covered? 1823 to 2003 at time of writing
range(interstate_wars$start_year)
#==========================plots=================
simple_caption <- "Source: Correlates of War, Inter-State War Data; analysis by freerangestats.info"
#-----------------distribution of duration------------
summary(interstate_wars$duration)
sim_norm <- data.frame(duration = 10 ^ (rnorm(1e6,
mean = log10(interstate_wars$duration),
sd = sd(log10(interstate_wars$duration)))))
interstate_wars |>
ggplot(aes(x = duration)) +
geom_density() +
geom_rug() +
geom_density(data = sim_norm, colour = "orange") +
annotate("text", x= 1, y = 0.18, label = "Simulated log-normal distribution",
colour = "orange", hjust = 0) +
annotate("text", x= 300, y = 0.51, label = "Empirical distribution of war durations",
colour = "black", hjust = 0) +
# carefully chosen labels for x axis:
scale_x_log10(label = comma, breaks = c(range(interstate_wars$duration), 10, 100, 1000)) +
labs(x = "Duration of wars (in days, logarithmic scale)",
y = "Density",
title = "Distribution of war durations, 1823 to 2003",
subtitle = "More concentrated, less-fat tails than a log-normal distribution",
caption = simple_caption) +
# use coord to limit x axis so statistical calculations are all done on full data:
coord_cartesian(xlim = c(1, 8000))
OK, deci principala mea sarcină analitică aici este să elaborez durata condiționată așteptată a unui război care a ajuns la 74 de zile – durata până acum a războiului SUA-Israel-Iran. Da, știu că există o încetare a focului respectată incomplet, dar există și o blocadă (sau două), iar acesta este fără ambiguitate un act de război conform dreptului internațional. Așa că consider războiul ca fiind în desfășurare.
Tabelul meu pentru a răspunde la această întrebare este acesta:
Ce se întâmplă aici este:
- funcția empirică de distribuție cumulativă a duratelor este linia întunecată – practic frecvența cumulativă pe axa verticală, dar exprimată ca proporție.
- linia gri este un simplu netezitor LOESS al acelei frecvențe cumulative, util pentru modelarea valorilor care nu se potrivesc exact în date.
- liniile roșii arată durata războiului actual și unde s-ar încadra în distribuția războaielor din 1823 până în 2003. Este aproximativ 0,33 (definit în codul de mai jos ca variabilă
current_cf), ceea ce înseamnă că războiul actual este deja mai lung decât aproximativ 33% din războaie. - linia albastră orizontală se află la jumătatea distanței în spațiul vertical dintre linia roșie orizontală și 1. Acolo unde se întâlnește cu linia netezită și scade o linie albastră verticală arată durata mediană așteptată a unui război care a ajuns la acest punct de 0,33 pe frecvența cumulativă.
Deci vedem că, în cazul războaielor care durează până la 74 de zile, ne așteptăm ca durata medie totală să fie de 261 de zile. Acest lucru este puțin sumbru pentru aceia dintre noi care cred că până și extinderea până în iunie va fi într-adevăr foarte rău pentru economia mondială, dar este bine de știut. Desigur, există o mulțime de războaie care ajung la 74 de zile și apoi se opresc la scurt timp după, așa că există speranță și acolo.
Iată codul pentru a face acel bit de inferență statistică și a desena diagrama:
#-------------------cumulative distribution--------------
interstate_cumulative <- interstate_wars |>
arrange(duration) |>
mutate(cumulative_freq = 1:n() / n())
# smoothed model of the cumulative distribution, including estimates of where
# the Iran war is on it:
model <- loess(cumulative_freq ~ log(duration), data = interstate_cumulative)
current_dur <- 74 # as at 13 May 2025 - war started 28 February 2026
current_cf <- predict(model, newdata = data.frame(duration = current_dur))
# inverse model to estimate duration given a cumulative frequency, useful for
# annotations on the chart:
inv_model <- loess(duration ~ x,
data = data.frame(duration = interstate_cumulative$duration,
x = fitted(model)))
# of wars that last this long, what is the median cumulative frequency (i.e. half-way to 1):
conditional_median_freq <- (1 + current_cf) / 2
# of wars with that median cumulative frequency, convert it back into a duration,
conditional_median_dur <- predict(inv_model, data.frame(x = conditional_median_freq))
# Draw chart of cumulative distribution:
interstate_cumulative |>
ggplot(aes(x = duration, y = cumulative_freq)) +
geom_smooth(method = "loess", colour = "grey80") +
geom_line() +
# note that (seems a bit odd) need to manually do the scale transform to geom_segment here:
geom_segment(x = log10(current_dur), xend = log10(current_dur), y = -Inf, yend = current_cf, colour = "red") +
geom_segment(x = 0, xend = log10(current_dur), y = current_cf, yend = current_cf, colour = "red") +
geom_segment(x = log10(conditional_median_dur), xend = log10(conditional_median_dur), y = -Inf, yend = conditional_median_freq, colour = "blue") +
geom_segment(x = 0, xend = log10(conditional_median_dur), y = conditional_median_freq, yend = conditional_median_freq, colour = "blue") +
annotate("text", x = current_dur * 0.95, y = 0.39, label = "Current Iran war", colour = "red", hjust = 1) +
annotate("text", x = conditional_median_dur * 1.05, y = 0.62, colour = "blue", hjust = 0, vjust = 1,
label = glue("Median expectation conditional
on at least {current_dur} days")) +
scale_x_log10(label = comma, breaks = c(10, current_dur, 100, conditional_median_dur, 1000)) +
labs(x = "Total duration of war (in days, logarithmic scale)",
y = "Cumulative frequency of wars",
title = "Expectations of duration of Iran war, based on modern inter-state wars' duration",
subtitle = glue("Comparison to wars from 1823 to 2003. The median war that lasts {current_dur} days goes on to last {round(conditional_median_dur)} days."),
caption = simple_caption)
Putem folosi aceeași abordare pentru a calcula nu doar durata medie a războiului (condiționată de a ajunge la 74 de zile), ci și alte percentile. De exemplu, în cele de mai jos putem construi un interval de predicție de 80% (între cuantilele 0,1 și 0,9) cu o durată totală de 94,9 și 1.752 de zile. Cu alte cuvinte, din acest punct de 74 de zile, doar 10% dintre războaie vor avea o durată totală de 94,9 sau mai puțină zile (adică încă 21 de zile).
Toate în sus, aceasta este o gamă mare desigur; Principalul lucru pe care ni-l spune este că războaiele durează mai mult decât și-ar dori mulți oameni și există o mare variație în durata războaielor.
# some prediction intervals, conditional on getting to 74 days:
probs <- c(0.05, 0.1, 0.5, 0.8, 0.9, 0.95)
more_freqs <- probs * (1 - current_cf) + current_cf
conditional_dur <- predict(inv_model, data.frame(x = more_freqs))
tibble(probability = probs, duration = conditional_dur)
# so 80% of wars that reach 74 days will have a total duration between 95 and 1,752 days
probability duration
1 0.05 82.3
2 0.1 94.9
3 0.5 261.
4 0.8 1141.
5 0.9 1752.
6 0.95 2119.
Durata și alți factori
Așa că îmi răspunsesem la întrebarea principală, dar eram în mod natural curioasă și despre alte relații. Evident, se așteaptă ca războaiele mai lungi să aibă mai multe morți în luptă; putem vedea asta în date? Da, putem:
Îmi place această diagramă ca prezentând amploarea a aproape două secole de război între state într-o vizualizare ușoară.
Vedem, de asemenea, că dacă există un model în relația între durată, decese și momentul în care a început războiul (anul de început este reprezentat de culoare în graficul de mai sus), acesta nu este unul evident. Vom reveni la asta în următorul grafic, dar mai întâi, iată codul pentru a crea diagrama de dispersie de mai sus.
#------------------Compare duration and number of deaths----------------
interstate_wars |>
ggplot(aes(x = duration, y = bat_death, label = war_name)) +
geom_point(aes(colour = start_year), size = 3.5) +
geom_text_repel(colour = "grey50", size = 2, seed = 123) +
scale_y_log10(label = comma) +
scale_x_log10(label = comma) +
scale_colour_viridis_c() +
labs(title = "Inter-state wars, 1823-2003",
colour = "Starting year",
x = "Duration in days",
y = "Number of battle deaths",
caption = simple_caption) +
theme(legend.position = c(0.15, 0.8))
Eram puțin îngrijorat de chestia aia cu „două secole”. Sunt războaiele recente toate mult mai scurte, sau poate mult mai lungi, decât războaiele mai vechi? Dacă da, ar fi o mare limitare a concluziei mele despre durata probabilă a războiului. Așa că am pregătit încă un complot pentru a verifica dacă a existat o relație evidentă, mai riguros decât o culoare atrăgătoare în complotul precedent. Am fost puțin surprins să văd că de fapt nu există o creștere sau o reducere reală a duratei războiului în timp:
De asemenea, îmi place foarte mult acest grafic, deoarece ne oferă o comparație instantanee a războiului nostru actual SUA-Israel-Iran cu unele dintre cele din istorie. Putem vedea că este deja mai lung decât Rebeliunea Boxer, dar nu chiar atât de lung ca Insulele Falkland sau Războiul pentru Kosovo (pentru toate aceste denumiri le folosesc pe cele oferite de proiectul Corelates of War – știu bine că acestea sunt etichete contestate).
Iată ultima mea bucată de cod care desenează ultimul grafic:
#------------Compare duration with when in history it happened---------------
interstate_wars |>
arrange(bat_death) |>
ggplot(aes(x = earliest_start, y = duration)) +
geom_hline(yintercept = current_dur, colour = "red") +
geom_point(aes(size = bat_death), shape = 1) +
geom_text_repel(aes(label = war_name), colour = "steelblue", size = 3, seed = 123) +
annotate("text", x= as.Date("1820-01-01"), y = current_dur + 8, hjust = 0,
label = "Duration of 2026 US-Israel-Iran war so far", colour = "red") +
scale_y_log10(label = comma) +
scale_size_area(label = comma, max_size = 25) +
labs(title = "Inter-state wars, 1823-2003",
subtitle = glue("Compared to the USA-Israel-Iran war as at {Sys.Date()}"),
x = "Start of war",
y = "Duration of war (days)",
size = "Number of batlle deaths:",
caption = simple_caption)
Asta e tot oameni buni. Rămâi în siguranță acolo.
