The hardware and bandwidth for this mirror is donated by dogado GmbH, the Webhosting and Full Service-Cloud Provider. Check out our Wordpress Tutorial.
If you wish to report a bug, or if you are interested in having us mirror your free-software or open-source project, please feel free to contact us at mirror[@]dogado.de.

Get started with contentiousR

contentiousR creates reproducible country-year panels for contentious politics and civil conflicts research, offers diagnostics and visualization tools, and allows interoperation with peacesciencer. Every public loader supports Correlates of War ("cow") and Gleditsch-Ward ("gw") country codes.

Build and enrich a panel

Construct a state panel, then add data.

library(contentiousR)

panel <- build_states_panel(
  start_year = 2000,
  end_year = 2002,
  coding_system = "cow"
)

analysis_data <- panel |>
  add_gdp() |>
  add_conflict("ucdp_prio") |>
  add_leader_data("archigos")

analysis_data[1:4, c(
  "country", "year", "gdp_pcap", "ucdp_prio_incidence", "leader"
)]
#>         country year gdp_pcap ucdp_prio_incidence    leader
#> 1 United States 2000 55889.52                  NA   Clinton
#> 2 United States 2001 55783.75                   1 G.W. Bush
#> 3 United States 2002 56127.44                   1 G.W. Bush
#> 4        Canada 2000 48531.95                  NA  Chretien

An unmatched row remains NA, as a source may not cover a country-year.

Load data separately

Standalone loaders are useful when you want to inspect or aggregate data before joining them.

conflicts <- conflict_data(
  start_year = 2000,
  end_year = 2002,
  dataset = "ucdp_prio",
  coding_system = "gw"
)

head(conflicts)
#> # A tibble: 6 × 13
#>      gw  year ucdp_prio_incidence ucdp_prio_onset ucdp_prio_n_conflicts
#>   <int> <dbl>               <int>           <int>                 <int>
#> 1     2  2001                   1               1                     2
#> 2     2  2002                   1               0                     1
#> 3   100  2000                   1               0                     1
#> 4   100  2001                   1               0                     1
#> 5   100  2002                   1               0                     1
#> 6   200  2001                   1               1                     1
#> # ℹ 8 more variables: ucdp_prio_intensity_max <int>, ucdp_prio_war <int>,
#> #   ucdp_prio_cumulative_intensity <int>, ucdp_prio_type_max <int>,
#> #   ucdp_prio_intrastate <int>, ucdp_prio_interstate <int>,
#> #   ucdp_prio_incompatibility_max <int>, ucdp_prio_ep_end <int>

UCDP/PRIO distinguishes active conflict-years (ucdp_prio_incidence) from the first year of an episode (ucdp_prio_onset). See vignette("data-sources", package = "contentiousR") before interpreting any source-specific variable.

Conflict spells (peace-years)

add_spell_duration() turns a binary conflict column into a duration counter — years since the last event for that state, restarting after each new one. This is the same construct as peacesciencer::add_spells() (named differently here to avoid colliding with it when both packages are attached), useful as a control for temporal dependence in event-history models (e.g. with cubic splines). It needs a column without NA, so filter first:

spell_data <- build_states_panel(1990, 2005, coding_system = "gw") |>
  add_conflict("ucdp_prio") |>
  tidyr::drop_na(ucdp_prio_onset) |>
  add_spell_duration(event = "ucdp_prio_onset")

spell_data[spell_data$gw == 2, c("gw", "year", "ucdp_prio_onset", "ucdp_prio_spell")]
#>   gw year ucdp_prio_onset ucdp_prio_spell
#> 1  2 2001               1               0
#> 2  2 2002               0               0
#> 3  2 2003               1               1
#> 4  2 2004               0               0
#> 5  2 2005               0               1

If event is omitted, add_spell_duration() looks for exactly one column ending in _onset, _incidence, or _ongoing and uses that; it errors if none or several are found. _onset-style columns treat every 1 as an independent event by default; _incidence/_ongoing-style columns collapse a run of consecutive 1s into one event, leaving the continuation years NA in the output (override this with the ongoing argument).

Lagged variables

add_lag() adds a lagged version of one or more columns, computed within each state after sorting by year and grouping by state before lagging. Unlike a plain dplyr::lag(), it checks that the preceding row is genuinely n years earlier, so a gap in the year sequence produces NA rather than silently reaching further back than intended:

build_states_panel(1990, 1995, coding_system = "cow") |>
  add_gdp() |>
  add_lag(vars = c("gdp_pcap", "gdp_growth"), n = 1) |>
  dplyr::filter(cow == 2) |>
  dplyr::select(cow, year, gdp_pcap, gdp_pcap_l, gdp_growth_l)
#> # A tibble: 6 × 5
#>     cow  year gdp_pcap gdp_pcap_l gdp_growth_l
#>   <dbl> <dbl>    <dbl>      <dbl>        <dbl>
#> 1     2  1990   45755.        NA         NA   
#> 2     2  1991   45035.     45755.         3.18
#> 3     2  1992   45912.     45035.        -1.58
#> 4     2  1993   46485.     45912.         1.95
#> 5     2  1994   47696.     46485.         1.25
#> 6     2  1995   48326.     47696.         2.60

Each requested variable gets one new column named <var>_l. Call add_lag() again (optionally with a different n) for additional lags.

Visualizing onsets

plot_coverage() draws a state-by-year heatmap of a binary (0/1) event column: 1 years are shaded as an event, 0 years as no event, and years where the source has no data — either var is NA, or the state does not appear in the panel that year at all, e.g. before independence — are left blank. States that never have the event are dropped by default (drop_empty = TRUE), since an all-blank/grey row adds clutter without showing where events actually happened.

if (requireNamespace("ggplot2", quietly = TRUE)) {
  build_states_panel(1990, 2015, coding_system = "cow") |>
    add_conflict("ucdp_prio") |>
    plot_coverage("ucdp_prio_onset")
}

Optional V-Dem data

V-Dem is not bundled and its R data package is not on CRAN. Install it from its official repository, then request only the indicators you need:

remotes::install_github("vdeminstitute/vdemdata")

panel |>
  add_vdem(c("v2x_polyarchy", "v2x_libdem"))

build_states_panel()

Creates a state-year panel with optional filters:

panel <- build_states_panel(
  start_year        = 1946,
  end_year          = 2019,
  coding_system     = "cow",   # or "gw"
  exclude_microstates = TRUE,
  exclude_non_un    = TRUE,
  exclude_islands   = FALSE
)

load_gdp_data() / add_gdp()

Two GDP sources are available via dataset. "gapminder" (default) returns gdp_pcap, log_gdp_pcap, and gdp_growth. "fariss" returns the latent GDP and GDP per capita estimates from Fariss, Anders, Markowitz, and Barnum (2022) as fariss_gdp and fariss_gdppc, with much wider coverage (1500–2019) but units that are not independently verified in this package — see vignette("data-sources", package = "contentiousR").

# Standalone
gdp <- load_gdp_data(start_year = 1990, end_year = 2015, coding_system = "cow")
fariss_gdp <- load_gdp_data(1700, 2015, dataset = "fariss", coding_system = "cow")

# Pipeline
panel |> add_gdp()
panel |> add_gdp(dataset = "fariss")

load_population_data() / add_population()

Three population sources are available via dataset.

Dataset Source Coverage Returned columns
"wpp" (default) UN World Population Prospects 2024 1949–2023 wpp_pop
"nmc" Correlates of War NMC v7.0 1816–2022 nmc_tpop, nmc_upop
"fariss" Fariss et al. (2022) latent estimate 1500–2019 fariss_pop
# Standalone
pop_wpp <- load_population_data(1990, 2015, dataset = "wpp", coding_system = "cow")
pop_nmc <- load_population_data(1900, 2015, dataset = "nmc", coding_system = "cow")

# Pipeline
panel |> add_population()
panel |> add_population(dataset = "nmc")

load_military_expenditure_data() / add_military_expenditure()

Three military expenditure sources are available via dataset.

Dataset Source Coverage Returned columns
"sipri" (default) SIPRI Military Expenditure Database 1949–2025 sipri_milex, sipri_milburden
"nmc" National Material Capabilities v7.0 1816–2022 nmc_milex
"barnum" Barnum et al. (2025) latent estimate 1816–2019 barnum_milburden, barnum_sipri, barnum_nmc
# Standalone
milex_sipri <- load_military_expenditure_data(1990, 2015, dataset = "sipri", coding_system = "cow")
milex_barnum <- load_military_expenditure_data(1900, 2015, dataset = "barnum", coding_system = "cow")

# Pipeline
panel |> add_military_expenditure()
panel |> add_military_expenditure(dataset = "barnum")

Unlike the Fariss GDP/population estimates, Barnum et al.’s underlying model does not publish a single combined military expenditure value on a real monetary scale, so barnum_sipri and barnum_nmc are the model’s posterior estimate of two specific indicators rather than one “latent” series. See vignette("data-sources", package = "contentiousR") for what each represents and why they are not directly comparable to sipri_milex / nmc_milex.

load_vdem_data() / add_vdem()

V-Dem indicators. A default set of democracy, civil society, civil liberties, and rule-of-law variables is loaded when vars = NULL.

# Standalone
vdem <- load_vdem_data(
  vars          = c("v2x_polyarchy", "v2x_libdem"),
  start_year    = 1990,
  end_year      = 2015,
  coding_system = "cow"
)

# Pipeline
panel |> add_vdem(vars = c("v2x_polyarchy", "v2x_libdem"))

load_leader_data() / add_leader_data()

Country-year leader data from two sources. Each row contains the leader who held power at the end of the year; in transition years the latest-starting leader is kept.

Dataset Source Coverage Key variables
"archigos" Archigos 4.1 1875–2015 entry, exit, irregular_entry, irregular_exit, female_leader, yrborn, posttenurefate, leader_tenure
"reign" REIGN Leader List 1921–2021 female_leader, military_bg, birthyear, leader_tenure
# Standalone
arch  <- load_leader_data(1990, 2015, dataset = "archigos", coding_system = "cow")
reign <- load_leader_data(1990, 2015, dataset = "reign",    coding_system = "gw")

# Pipeline
panel |> add_leader_data(dataset = "archigos")
panel |> add_leader_data(dataset = "reign")

Interoperate with peacesciencer

contentiousR supports peacesciencer (see Miller 2022). It means you can add data from peacesciencer within the same data construction pipeline.

Functions such as peacesciencer::add_archigos() expect ccode/gwcode keys plus attributes that describe the state system and unit of analysis. Use add_from_peacesciencer() to supply these temporarily and return a panel with only contentiousR’s original country-code key:

library(peacesciencer)

analysis_data |>
  add_from_peacesciencer(peacesciencer::add_archigos)

For multiple consecutive additions, call as_peacesciencer_panel() once and then apply the peacesciencer functions directly. Neither helper changes country codes, rows, or substantive variables.

References

Barnum, M., Fariss, C. J., Markowitz, J. N., & Morales, G. (2025). Measuring arms: Introducing the global military spending dataset. Journal of Conflict Resolution, 69(2-3), 540-567. https://doi.org/10.1177/00220027241232964

Fariss, C. J., Anders, T., Markowitz, J. N., & Barnum, M. (2022). New estimates of over 500 years of historic GDP and population data. Journal of Conflict Resolution, 66(3), 553-591. https://doi.org/10.1177/00220027211054432

Miller, S. V. (2022). {peacesciencer}: An R package for quantitative peace science research. Conflict Management and Peace Science, 39(6), 755-779. https://doi.org/10.1177/07388942221077926

Singer, J. David. (1988). Reconstructing the Correlates of War Dataset on Material Capabilities of States, 1816-1985. International Interactions, 14: 115-32.

Singer, J. David, Stuart Bremer, and John Stuckey. (1972). “Capability Distribution, Uncertainty, and Major Power War, 1820-1965.” in Bruce Russett (ed) Peace, War, and Numbers, Beverly Hills: Sage, 19-48.

These binaries (installable software) and packages are in development.
They may not be fully stable and should be used with caution. We make no claims about them.
Health stats visible at Monitor.