ucdpR is a toolkit for reproducible research with data from the Uppsala Conflict Data Program. It provides a consistent R interface for finding, downloading, importing, documenting, validating, spatially preparing, and comparing UCDP datasets. Downloading data is the foundation, but the package is designed to grow around the wider tasks that applied researchers repeatedly encounter when working with UCDP data.
The package currently helps researchers:
- discover available datasets without hard-coding download URLs;
- download or directly import current and historical releases;
- pin exact versions for reproducible research;
- preserve source URLs, versions, retrieval details, and file checksums;
- retrieve official codebooks and dataset citation guidance;
- discover official version histories and publication replication materials;
- validate common identifiers, dates, fatality estimates, coordinates, and codes;
- inspect schemas and summarize or filter event precision;
- aggregate events and fatality bounds to common analytical units;
- construct complete, explicitly labelled yearly and monthly panels;
- create provenance-preserving
sfpoint data; - assign georeferenced events to cells from the released
priogridpackage; - harmonize year-sensitive Gleditsch-Ward and CoW country codes;
- prepare state-year and dyad-year data for
peacesciencer; and - audit retrospective changes between two releases.
Because the catalog is read from the official download center at run time, new UCDP releases generally do not require a package update. ucdpR does not bundle or redistribute UCDP data.
Guides
The package includes a concise getting-started guide and five detailed vignettes:
vignette("getting-started", package = "ucdpR")
vignette("accessing-and-versioning", package = "ucdpR")
vignette("spatial-workflows", package = "ucdpR")
vignette("uncertainty-and-revisions", package = "ucdpR")
vignette("reproducible-research", package = "ucdpR")
vignette("interoperability", package = "ucdpR")Find and import data
library(ucdpR)
# See all current downloadable data files
catalog <- ucdp_catalog()
# Search without remembering exact titles
ucdp_search("georeferenced|candidate", catalog)
# Download a reproducible local copy
path <- ucdp_download("ged", format = "csv", dest_dir = "data-raw")
# Or download and import it directly
ged <- ucdp_get("ged", format = "csv")
# Inspect and download a frozen historical release
ucdp_versions("ged", format = "csv")
ged_24 <- ucdp_get("ged", version = "24.1", format = "csv")
# Monthly Candidate releases can be pinned in the same way
candidate <- ucdp_get("candidate", version = "25.0.12", format = "csv")
# Select a specific file when a dataset has multiple variants
brd <- ucdp_get("brd", variant = "dyadic", format = "csv")For reproducible research, specify version explicitly and record the returned filename, source metadata, and checksum. Imported objects retain these details in their ucdp_source attribute. Cite the dataset as requested by UCDP and avoid silently replacing frozen research data. ucdp_cite("ged") retrieves the current citation guidance.
Document provenance and retrieve codebooks
Objects imported with ucdp_get() retain their source record, exact version, retrieval time, checksum, and the package version used. Summarize these details alongside basic data coverage with:
ucdp_metadata(ged)
# Metadata can also be inspected before downloading a release
ucdp_metadata("ged", version = "24.1")Download the official codebook listed with a dataset:
ucdp_codebook("ged", dest_dir = "documentation")When several distinct documents match, refine the request with variant. Historical requests return only codebooks explicitly associated with the requested version and never silently substitute current documentation.
Retrieve the corresponding official version history where one exists:
ucdp_version_history("prio", version = "24.1")Inspect structure and precision
Inspect variable classes, missingness, uniqueness, ranges, and examples:
ucdp_schema(ged)For GED-style event data, summarize spatial and temporal precision:
ucdp_precision(ged)
ucdp_precision(ged, by = "year")
precise <- ucdp_filter_precision(
ged,
where_prec = 1:2,
date_prec = 1:3
)Precision filters are explicit: the requested numeric codes remain visible in the analysis script, and missing values can be dropped, retained, or treated as an error.
Aggregate events and construct panels
Aggregate event counts and available low, best, and high fatality estimates to country, PRIO-GRID, conflict, or dyad units:
country_year <- ucdp_aggregate(ged, unit = "country-year")
fatalities <- ucdp_fatalities(
ged,
by = c("country_id", "country", "year")
)Yearly and monthly units are supported. For monthly aggregation, existing year and month columns are used when available; otherwise the period can be derived from a date column.
Construct a complete panel directly from raw data or from an aggregation:
country_panel <- ucdp_panel(
ged,
unit = "country-year",
start = 1989,
end = 2025,
fill = "zero"
)Inserted rows are marked with .ucdp_observed = FALSE and .ucdp_fill = "zero_filled". This distinction is important: a zero-filled combination is an analytical construction and is not presented as an observed source record. Use fill = "missing" when absence should remain NA, and pass an explicit universe to include entities that never occur in the input.
Interoperate with priogrid and peacesciencer
Assign GED events to the configured half-degree grid from the released priogrid package:
# priogrid is currently installed from GitHub; sf and terra are also required
# renv::install("prio-data/priogrid")
ged_pg <- ucdp_to_priogrid(ged)
grid_year <- ucdp_aggregate(ged_pg, unit = "grid-year", id = "pgid")Country-code conversion is year-sensitive. By default, the mapping is built from peacesciencer; a frozen year/gwcode/ccode table may instead be supplied through crosswalk for exact replication:
country_year <- ucdp_country_crosswalk(
country_year,
from = "gw",
code = "country_id"
)
ps_country_year <- ucdp_to_peacesciencer(
country_year,
type = "state-year",
system = "gw",
code = "country_id"
)The bridge standardizes keys and declares peacesciencer attributes; it does not silently aggregate duplicate observations. This makes unit-of-analysis decisions visible in the research script. The output conventions (pgid, gwcode, ccode, and year) are intentionally simple so a future priogridR package can support them without breaking existing workflows.
Prepare spatial data
Convert event coordinates to an sf object while retaining UCDP provenance:
ged_sf <- ucdp_as_sf(ged)sf is optional and is only required for spatial conversion. The resulting EPSG 4326 point data provide a stable basis for later spatial joins, including workflows with the released priogrid package and the planned priogridR.
Retrieve publication replication files
UCDP maintains a publication-specific archive containing frozen datasets, codebooks, version histories, appendices, and special data variants:
replication <- ucdp_replication_catalog(year = 2025)
ucdp_replication_download(
"ged",
version = "25.1",
dest_dir = "replication"
)Ambiguous download requests fail unless they are refined or download_all = TRUE is supplied.
Validate imported data
ucdp_validate() performs transparent, non-destructive diagnostics:
validation <- ucdp_validate(ged)
validation$summary
validation$issuesThe function checks plausible observation keys, date consistency, fatality bounds, coordinate ranges, and selected UCDP categorical codes when the relevant variables are present. Warnings flag values for inspection rather than asserting that UCDP made a coding error. Use strict = TRUE when warnings should also make the overall result invalid.
Compare releases
UCDP datasets can be retrospectively revised. ucdp_compare_versions() turns two official releases into a structured revision audit:
comparison <- ucdp_compare_versions(
"ged",
old_version = "24.1",
new_version = "25.1"
)
comparison$overview # added, removed, modified, and unchanged rows
comparison$variables # number of revisions by variable
comparison$added # complete newly added observations
comparison$removed # complete removed observations
comparison$modified # keys and variables changed in matched observationsFor cell-level old and new values, set detail = "cells". For large releases where only counts are required, use detail = "summary" to limit memory use.
Package direction
Future convenience functions will build on the same principles: reproducible inputs, explicit versions, transparent transformations, and outputs that fit ordinary R workflows. The aim is to reduce recurring data-management work for UCDP users while keeping analytical choices visible and under the researcher’s control.