This tutorial covers working with PRIOGRID data as spatial rasters
using the terra package. Rasters are useful for
visualization, spatial analysis, and working with individual variables
before converting to tabular form.
All raster-related functions in PRIOGRID require
terra:
install.packages("terra")
library(terra)The Reference Grid
prio_blank_grid() creates an empty
SpatRaster filled with PRIOGRID cell IDs
(pgid). This is useful to understand the grid geometry and
to attach values for plotting:
pg <- prio_blank_grid()
pg
# class : SpatRaster
# dimensions : 360, 720, 1 (nrow, ncol, nlyr)
# resolution : 0.5, 0.5 (x, y)
# extent : -180, 180, -90, 90 (xmin, xmax, ymin, ymax)
# coord. ref. : lon/lat WGS 84 (EPSG:4326)
# source(s) : memory
# name : pgid
terra::plot(pg)Loading a Single Variable
load_pgvariable() downloads (if needed) and returns any
PRIOGRID variable as a SpatRaster. By default it uses the
official release:
ucdp <- load_pgvariable("ucdp_ged")
ucdpEach layer corresponds to one time step. Layer names are dates in
"YYYY-MM-DD" format:
names(ucdp)[1:5]
# [1] "1989-12-31" "1990-12-31" "1991-12-31" "1992-12-31" "1993-12-31"Select a single layer by name:
Loading Static Variables as Rasters
Static variables (no time dimension) are returned as a named list of
single-layer SpatRaster objects:
static_rasters <- read_pg_static(as_raster = TRUE)
names(static_rasters)
# Plot terrain ruggedness
terra::plot(static_rasters[["ruggedterrain_elevation_mean"]])Loading Time-Varying Variables as Rasters
Time-varying variables are returned as a named list, each element
being a multi-layer SpatRaster:
tv_rasters <- read_pg_timevarying(as_raster = TRUE)
# Each element is a SpatRaster with one layer per year
tv_rasters[["cru_tmp"]]Plotting Variables with plot_pgvariable()
plot_pgvariable() renders a variable with sensible
defaults pulled from its embedded pg_* metadata (label,
unit, display transform, colormap, value range) — no manual styling
needed. It wraps terra::plot(), so it needs only
terra (already required for rasters).
# Plot from a loaded raster:
r <- load_pgvariable("ucdp_ged")
plot_pgvariable(r, layer = "2020-12-31")
# Plot directly from a variable name:
plot_pgvariable("cru_tmp")Restrict the read to a region — a bounding box
c(xmin, xmax, ymin, ymax) in lon/lat, or a continent name.
When x is a variable name, only the COG blocks covering
that region are fetched (windowed read):
plot_pgvariable("cru_tmp", extent = "Africa")
plot_pgvariable("cru_tmp", extent = c(-20, 55, -35, 40))Overlay historically correct country borders
(add_borders, from cShapes, matched to the layer’s date), a
land outline (add_ne, from Natural Earth), and a
data-source citation in the margin (add_citation). The
border and land overlays require the cShapes and Natural Earth raw data
locally:
plot_pgvariable("ucdp_ged", layer = "1999-12-31", extent = "Africa",
add_borders = TRUE, add_ne = TRUE, add_citation = TRUE)Extra arguments pass through to terra::plot(),
overriding the metadata defaults:
plot_pgvariable(r, main = "Custom title")Discovering Variables with pgsearch()
pgsearch() searches the meta-data across source names,
versions, tags, spatial extent, and temporal resolution:
results <- pgsearch("climate")
# Returns a named list of data frames for each search category
# Which sources match by tag?
results$in_tags[, c("source_name", "tags")]
#> # A tibble: 4 × 2
#> source_name tags
#> <chr> <chr>
#> 1 CRU Climate tmp climate, validation, temperature
#> 2 CRU Climate pre climate, validation, precipitation
#> 3 CRU Climate pet climate, validation, evapotranspiration
#> 4 Global SPEI database drought index, climateSearch by tag to find related variables:
conflict_sources <- pgsearch("conflict")$in_tags
conflict_sources[, c("source_name", "temporal_resolution")]
#> # A tibble: 3 × 2
#> source_name temporal_resolution
#> <chr> <chr>
#> 1 UCDP GED Higher than monthly
#> 2 Armed Conflict Location & Event Data (ACLED) Higher than monthly
#> 3 UCDP GED Higher than monthlyConverting Rasters Back to Data Frames
rast_to_df() converts a SpatRaster to a
data.table with pgid (and
measurement_date for time-varying data):
r <- load_pgvariable("ruggedterrain_elevation_mean")
df <- rast_to_df(r, static = TRUE, varname = "ruggedterrain_elevation_mean")
head(df)
# pgid ruggedterrain_elevation_mean
# 1: 1 NA
# 2: 2 NA
# ...For time-varying data, set static = FALSE:
r <- load_pgvariable("cru_tmp")
df <- rast_to_df(r, static = FALSE, varname = "cru_tmp")
head(df)
# pgid measurement_date cru_tmp
# 1: 1 1901-12-31 NACombining Rasters with terra
terra supports stacking, arithmetic, and many other
operations. Here are a few patterns:
# Stack two variables for combined analysis
elev <- load_pgvariable("ruggedterrain_elevation_mean")
pop <- load_pgvariable("ghsl_population_grid")[["2020-12-31"]]
# Crop to a region (e.g., Sub-Saharan Africa)
africa_ext <- terra::ext(c(-20, 55, -35, 40))
elev_africa <- terra::crop(elev, africa_ext)
pop_africa <- terra::crop(pop, africa_ext)
terra::plot(c(elev_africa, log1p(pop_africa)),
main = c("Elevation", "Population (log)"))Saving and Reusing Custom Results
save_pgvariable() writes any SpatRaster to
the dataset’s cog/ sub-folder as a Cloud-Optimized GeoTIFF
({varname}.tif), stamping layer dates via
time(), units(), and the pg_*
display metadata from pgvariables so the file is
self-describing:
r <- gen_ruggedterrain_elevation_mean()
save_pgvariable(r, "ruggedterrain_elevation_mean")
# Later, load it back:
r2 <- load_pgvariable("ruggedterrain_elevation_mean")Next Steps
- Custom Configurations — building variables at custom resolutions and extents
-
Understanding PRIOGRID Metadata —
exploring
pgsourcesandpgvariables