PRIOGRID is an R package for collecting and standardizing open
spatial data into a common grid format. This tutorial covers the basics:
setting up the package, downloading data, and reading it into R as
tabular data. Reading cached tables needs only arrow
(installed automatically); the first read after download builds those
tables from the downloaded GeoTIFFs and needs terra.
Initial Setup
PRIOGRID stores raw downloaded data and processed outputs in a single folder on your machine. This path persists across R sessions.
library(priogrid)
# Set the data folder (run once; persists across sessions)
pg_set_rawfolder("/path/to/your/data/folder")Once set, you can retrieve it at any time:
Configuration
PRIOGRID has a session-scoped configuration object that controls the spatial and temporal parameters of the grid. The defaults match the official PRIOGRID release:
pg_current_config()
#> PRIO-GRID config:
#> nrow: 360
#> ncol: 720
#> crs: epsg:4326
#> extent: -180 180 -90 90
#> temporal_resolution: 1 year
#> start_date: 1850-12-31
#> end_date: 2026-09-24
#> verbose: TRUE
#> automatic_download: TRUE| Parameter | Default | Meaning |
|---|---|---|
nrow / ncol
|
360 / 720 | Grid dimensions (0.5° cells) |
crs |
"epsg:4326" |
WGS84 geographic coordinates |
extent |
global | -180 to 180, -90 to 90 |
temporal_resolution |
"1 year" |
Annual time steps |
start_date |
1850-12-31 |
First measurement date |
end_date |
today | Last measurement date |
You can inspect individual fields:
cfg <- pg_current_config()
cfg$nrow
#> [1] 360
cfg$temporal_resolution
#> [1] "1 year"The configuration is only in effect for the current R session. See the Custom Configurations vignette for how to change it.
Downloading the Official Release
Download the current official PRIOGRID release with a single call.
This fetches the variables as individual Cloud-Optimized GeoTIFFs (plus
a pg_config.json manifest and _checksums.csv)
into your raw data folder:
To see what releases are available:
download_priogrid(list_releases = TRUE)The download only happens once — subsequent calls are skipped unless
you set overwrite = TRUE.
Reading PRIOGRID Data
Once downloaded, load the full dataset as a data.table.
The first read builds the table from the downloaded COGs and needs
terra; every read after that uses the cached Parquet and
needs only arrow (installed automatically).
Static Variables
Static variables do not change over time (e.g., terrain elevation, country border distances):
pg_static <- read_pg_static()
head(pg_static)Each row is a PRIOGRID cell identified by pgid. Columns
are variable names.
Time-Varying Variables
Time-varying variables have a measurement_date column in
addition to pgid:
pg_tv <- read_pg_timevarying()
head(pg_tv)These tables can be joined together by pgid, or merged
with your own data.
Subsetting at read time
All six filter arguments default to NULL (no filter —
full dataset). When supplied, filters are pushed down to Arrow before
any data is collected, so only the requested rows and columns touch
memory. Temporal and spatial constraints compose as AND;
pgids and extent compose as union.
| Argument | Type | Effect |
|---|---|---|
years |
integer vector | Keep only the listed calendar years (prunes hive partitions) |
start_date / end_date
|
Date | Inclusive bounds on measurement_date
|
pgids |
integer vector | Keep specific PRIO-GRID cell IDs |
extent |
c(xmin, xmax, ymin, ymax) in lon/lat |
Bounding box resolved to cell IDs (requires terra) |
variables |
character vector | Return only the named variable columns |
# A single year
pg_2020 <- read_pg_timevarying(years = 2020)
# Inclusive date range
pg_decade <- read_pg_timevarying(
start_date = as.Date("2010-01-01"),
end_date = as.Date("2019-12-31")
)
# Spatial bounding box (Sub-Saharan Africa)
pg_africa <- read_pg_timevarying(
extent = c(xmin = -20, xmax = 55, ymin = -35, ymax = 40)
)
# One variable column only
pg_tmp <- read_pg_timevarying(variables = "cru_tmp")
# Combined: two years, one region, two variables
pg_sub <- read_pg_timevarying(
years = c(2010, 2015),
extent = c(xmin = -20, xmax = 55, ymin = -35, ymax = 40),
variables = c("cru_tmp", "ucdp_ged")
)Example: merging static and time-varying data
library(data.table)
# Load a specific year and region with push-down, then merge with static data
pg_tv <- read_pg_timevarying(
years = 2020,
extent = c(xmin = -20, xmax = 55, ymin = -35, ymax = 40)
)
pg_merged <- merge(pg_static, pg_tv, by = "pgid")Browsing Available Variables
The pgvariables data frame lists all variables in
PRIOGRID:
pgvariables
#> name static
#> 1 cru_tmp FALSE
#> 2 cru_pre FALSE
#> 3 cru_pet FALSE
#> 4 cshapes_cover_share FALSE
#> 5 cshapes_gwcode FALSE
#> 6 geoepr_reg_excluded FALSE
#> 7 bdist1 FALSE
#> 8 bdist2 FALSE
#> 9 bdist3 FALSE
#> 10 ghsl_population_grid FALSE
#> 11 hilda_cropland FALSE
#> 12 hilda_forest FALSE
#> 13 hilda_grassland FALSE
#> 14 hilda_ocean FALSE
#> 15 hilda_pasture FALSE
#> 16 hilda_sparse FALSE
#> 17 hilda_urban FALSE
#> 18 hilda_water FALSE
#> 19 linight_mean FALSE
#> 20 naturalearth_cover TRUE
#> 21 naturalearth_cover_share TRUE
#> 22 ruggedterrain_elevation_mean TRUE
#> 23 traveltime_mean TRUE
#> 24 traveltime_min TRUE
#> 25 geopko_troops_count FALSE
#> 26 geopko_operations_count FALSE
#> 27 ne_disputed_area_share TRUE
#> 28 speibase6_mean FALSE
#> 29 ghs_wup_degurba_urban FALSE
#> 30 ucdp_ged FALSE
#> 31 shdi FALSE
#> 32 msch FALSE
#> 33 esch FALSE
#> 34 lifexp FALSE
#> 35 gnic FALSE
#> 36 side_excluded FALSE
#> 37 side_included FALSE
#> 38 side_irrelevant FALSE
#> source_ids
#> 1 ac037134-3567-49d9-a3ba-64f37c1ee698
#> 2 00575260-ad1c-4e87-a575-3922bc151f50
#> 3 95399c70-7db4-47f0-95e5-2e279b6b2054
#> 4 ec3eea2e-6bec-40d5-a09c-e9c6ff2f8b6b
#> 5 ec3eea2e-6bec-40d5-a09c-e9c6ff2f8b6b
#> 6 287bfdf7-2f4f-402a-88df-5fe1f8b7046b, 3900b527-a728-4c26-b0ab-f4441d3ee2e8
#> 7 ec3eea2e-6bec-40d5-a09c-e9c6ff2f8b6b
#> 8 ec3eea2e-6bec-40d5-a09c-e9c6ff2f8b6b
#> 9 ec3eea2e-6bec-40d5-a09c-e9c6ff2f8b6b
#> 10 ae6a7612-4bef-452f-acd6-d2212cf9a7c5
#> 11 82bc4c6f-9904-484f-aa9a-77771d076690
#> 12 82bc4c6f-9904-484f-aa9a-77771d076690
#> 13 82bc4c6f-9904-484f-aa9a-77771d076690
#> 14 82bc4c6f-9904-484f-aa9a-77771d076690
#> 15 82bc4c6f-9904-484f-aa9a-77771d076690
#> 16 82bc4c6f-9904-484f-aa9a-77771d076690
#> 17 82bc4c6f-9904-484f-aa9a-77771d076690
#> 18 82bc4c6f-9904-484f-aa9a-77771d076690
#> 19 d99fbea7-2a01-4221-b900-29a58d33f591
#> 20 92da9800-4520-4e87-a855-b28255452189
#> 21 92da9800-4520-4e87-a855-b28255452189
#> 22 8c8192eb-cc29-4598-8f8a-ec190ba35c2d
#> 23 9aa052f6-4d04-4ed1-9eed-e47e08828d38
#> 24 9aa052f6-4d04-4ed1-9eed-e47e08828d38
#> 25 7dcbfbfb-9667-4684-af34-85f69fa8d0a0
#> 26 7dcbfbfb-9667-4684-af34-85f69fa8d0a0
#> 27 920663ad-d7e7-4528-b36d-4b7266def2b1
#> 28 14839384-623a-4cf7-9241-6166a8ac465b, 95399c70-7db4-47f0-95e5-2e279b6b2054, 00575260-ad1c-4e87-a575-3922bc151f50
#> 29 7f1f60a3-6664-4427-b086-b5359ebf45b7
#> 30 49f79d96-4e4d-4812-9dd1-862bacfca577
#> 31 8aaf6b27-6372-43da-87a9-d4235095bb2c, a8e35e36-9f7e-4194-9cc4-ce8ca59f7b51, 8aaf6b27-6372-43da-87a9-d4235095bb2c
#> 32 8aaf6b27-6372-43da-87a9-d4235095bb2c, a8e35e36-9f7e-4194-9cc4-ce8ca59f7b51, 8aaf6b27-6372-43da-87a9-d4235095bb2c
#> 33 8aaf6b27-6372-43da-87a9-d4235095bb2c, a8e35e36-9f7e-4194-9cc4-ce8ca59f7b51, 8aaf6b27-6372-43da-87a9-d4235095bb2c
#> 34 8aaf6b27-6372-43da-87a9-d4235095bb2c, a8e35e36-9f7e-4194-9cc4-ce8ca59f7b51, 8aaf6b27-6372-43da-87a9-d4235095bb2c
#> 35 8aaf6b27-6372-43da-87a9-d4235095bb2c, a8e35e36-9f7e-4194-9cc4-ce8ca59f7b51, 8aaf6b27-6372-43da-87a9-d4235095bb2c
#> 36 e42b30e3-75da-4dd4-a375-0d6557087804
#> 37 e42b30e3-75da-4dd4-a375-0d6557087804
#> 38 e42b30e3-75da-4dd4-a375-0d6557087804
#> label unit
#> 1 Mean temperature °C
#> 2 Precipitation mm
#> 3 Potential evapotranspiration mm/day
#> 4 State territory coverage (share) <NA>
#> 5 Country (Gleditsch-Ward code) <NA>
#> 6 Excluded ethnic groups (regional, share) <NA>
#> 7 Distance to nearest land border m
#> 8 Distance to nearest international border m
#> 9 Distance to own country border m
#> 10 Population count persons
#> 11 Cropland cover (share) <NA>
#> 12 Forest cover (share) <NA>
#> 13 Grassland cover (share) <NA>
#> 14 Ocean cover (share) <NA>
#> 15 Pasture cover (share) <NA>
#> 16 Sparse vegetation cover (share) <NA>
#> 17 Urban cover (share) <NA>
#> 18 Water cover (share) <NA>
#> 19 Nighttime light (harmonized, mean) <NA>
#> 20 Land cover mask (share) <NA>
#> 21 Land cover (share) <NA>
#> 22 Mean elevation m
#> 23 Travel time to major city (mean) minutes
#> 24 Travel time to major city (minimum) minutes
#> 25 UN peacekeeping troops (count) personnel
#> 26 UN peacekeeping operations (count) <NA>
#> 27 Disputed area coverage (share) <NA>
#> 28 SPEI drought index (6-month, mean) <NA>
#> 29 Urban area (DEGURBA, share) <NA>
#> 30 Battle-related deaths (UCDP GED) deaths
#> 31 Subnational Human Development Index <NA>
#> 32 Mean years of schooling years
#> 33 Expected years of schooling years
#> 34 Life expectancy at birth years
#> 35 GNI per capita 1000 USD (2011 PPP)
#> 36 Excluded ethnic population (share) <NA>
#> 37 Included ethnic population (share) <NA>
#> 38 Politically irrelevant ethnic population (share) <NA>
#> transform plot_type
#> 1 identity continuous
#> 2 identity positive_real
#> 3 identity positive_real
#> 4 identity share
#> 5 identity discrete
#> 6 identity share
#> 7 identity positive_real
#> 8 identity positive_real
#> 9 identity positive_real
#> 10 log10 positive_real
#> 11 identity share
#> 12 identity share
#> 13 identity share
#> 14 identity share
#> 15 identity share
#> 16 identity share
#> 17 identity share
#> 18 identity share
#> 19 identity positive_real
#> 20 identity share
#> 21 identity share
#> 22 identity continuous
#> 23 identity positive_real
#> 24 identity positive_real
#> 25 log1p count
#> 26 log1p count
#> 27 identity share
#> 28 identity continuous
#> 29 identity share
#> 30 log1p count
#> 31 identity positive_real
#> 32 identity positive_real
#> 33 identity positive_real
#> 34 identity positive_real
#> 35 identity positive_real
#> 36 identity share
#> 37 identity share
#> 38 identity shareThe static column indicates whether a variable varies
over time. Use this to filter:
# Static variables
pgvariables[pgvariables$static == TRUE, "name"]
#> [1] "naturalearth_cover" "naturalearth_cover_share"
#> [3] "ruggedterrain_elevation_mean" "traveltime_mean"
#> [5] "traveltime_min" "ne_disputed_area_share"
# Time-varying variables
pgvariables[pgvariables$static == FALSE, "name"]
#> [1] "cru_tmp" "cru_pre"
#> [3] "cru_pet" "cshapes_cover_share"
#> [5] "cshapes_gwcode" "geoepr_reg_excluded"
#> [7] "bdist1" "bdist2"
#> [9] "bdist3" "ghsl_population_grid"
#> [11] "hilda_cropland" "hilda_forest"
#> [13] "hilda_grassland" "hilda_ocean"
#> [15] "hilda_pasture" "hilda_sparse"
#> [17] "hilda_urban" "hilda_water"
#> [19] "linight_mean" "geopko_troops_count"
#> [21] "geopko_operations_count" "speibase6_mean"
#> [23] "ghs_wup_degurba_urban" "ucdp_ged"
#> [25] "shdi" "msch"
#> [27] "esch" "lifexp"
#> [29] "gnic" "side_excluded"
#> [31] "side_included" "side_irrelevant"Rawfolder Structure
After downloading, your data folder has this structure:
{rawfolder}/
├── priogrid/
│ └── releases/
│ └── 3.0.2/
│ └── 05deg_yearly/
│ ├── cog/
│ │ └── {varname}.tif # Downloaded: variables as Cloud-Optimized GeoTIFFs
│ ├── pg_config.json # Downloaded: dataset manifest (grid, layout, variables)
│ ├── _checksums.csv # Downloaded, then extended locally: per-file MD5s
│ ├── pg_static.parquet # Built locally on first read_pg_static()
│ └── timevarying/ # Built locally on first read_pg_timevarying()
│ └── year=YYYY/
│ └── part-0.parquet # Hive-partitioned time-varying data
├── {source_name}/{version}/{id}/ # Raw source files (only if you build variables yourself)
└── tmp/ # Temporary processing files
download_priogrid() fetches the Cloud-Optimized GeoTIFFs
(cog/*.tif), the pg_config.json manifest, and
_checksums.csv from the PRIO CDN — there is no zip archive.
The tabular tables are built locally the first time you call
read_pg_static() / read_pg_timevarying():
read_pg_static() writes pg_static.parquet and
read_pg_timevarying() writes the hive-partitioned
timevarying/ dataset (both require terra).
Subsequent reads use these cached files and push any filters down to
Arrow first — no terra needed. Individual COGs are read
directly by load_pgvariable(). The compressed CSV bundles
(pg_static.csv.gz, pg_timevarying.csv.gz) are
not part of the CDN release; they are produced only by
build_release() for the zip download on
prio.org/data/40.
Next Steps
-
Accessing PRIOGRID as
Rasters — using
terrato work with individual variables as spatial rasters - Citations and Bibliography — how to cite data providers
- Custom Configurations — changing resolution, extent, and time period
-
Understanding PRIOGRID Metadata —
exploring
pgsources,pgvariables, andpgsearch()