| Title: | Actuarial Climate Index |
| Version: | 0.1.0 |
| Description: | Computes the Actuarial Climate Index (ACI) and its components (temperature, precipitation, drought, wind, sea level) from gridded climate data ('NetCDF') and tide gauge records. Implements the methodology described in Garrido, Milhaud & Olympio (2025) https://hal.science/hal-04491982v2 for a French/European actuarial climate index, building on the American Academy of Actuaries framework, to any country in the world. |
| License: | MIT + file LICENSE |
| URL: | https://github.com/XavierMilhaud/xaci |
| BugReports: | https://github.com/XavierMilhaud/xaci/issues |
| Encoding: | UTF-8 |
| Depends: | R (≥ 4.1.0) |
| Imports: | ncdf4 (≥ 1.19), dplyr (≥ 1.1), zoo (≥ 1.8), readr (≥ 2.1), ggplot2 (≥ 3.4.0), tidyr, sf, rnaturalearth, geodata, terra, units, parallel |
| Suggests: | testthat (≥ 3.0.0), patchwork (≥ 1.1.0), ecmwfr (≥ 2.0.0), rnaturalearthdata, gganimate, gifski, knitr, rmarkdown, spelling |
| RoxygenNote: | 7.3.3 |
| VignetteBuilder: | knitr |
| Language: | en-US |
| NeedsCompilation: | no |
| Packaged: | 2026-08-13 12:09:40 UTC; XM |
| Author: | Xavier Milhaud [aut, cre, ctb], Dabakh Kane [ctb], Esteban Mauboussin [ctb] |
| Maintainer: | Xavier Milhaud <xavier.milhaud.research@gmail.com> |
| Repository: | CRAN |
| Date/Publication: | 2026-09-09 15:20:02 UTC |
xaci: Actuarial Climate Index
Description
Computes the Actuarial Climate Index (ACI) and its components (temperature, precipitation, drought, wind, sea level) from gridded climate data ('NetCDF') and tide gauge records. Implements the methodology described in Garrido, Milhaud & Olympio (2025) https://hal.science/hal-04491982v2 for a French/European actuarial climate index, building on the American Academy of Actuaries framework, to any country in the world.
Author(s)
Maintainer: Xavier Milhaud xavier.milhaud.research@gmail.com [contributor]
Other contributors:
Dabakh Kane kanedabakh55@gmail.com [contributor]
Esteban Mauboussin esteban.mauboussin@cnp.fr [contributor]
See Also
Useful links:
Aggregate a 3-D climate array along the time dimension
Description
Aggregate a 3-D climate array along the time dimension
Usage
.aggregate_granularity_array(data, time, granularity = "month", FUN = mean)
Arguments
data |
Numeric array |
time |
POSIXct vector of length |
granularity |
One of |
FUN |
Aggregation function. Default |
Value
A list with data (array [nl x nw x nt_agg]),
and time (character vector of period labels, same convention
as aggregate_granularity()).
Build standard ERA5 file paths from country and years
Description
Internal helper that reconstructs the paths produced by
download_era5_all() and download_mask().
Usage
.build_era5_paths(country_abbrev, years, base_dir = NULL)
Arguments
country_abbrev |
ISO-3 country code (e.g. |
years |
Integer vector of years (e.g. |
base_dir |
Root data directory. If |
Value
A named list with elements t2m, tp, u10,
v10, and mask.
Compute the ACI at grid-cell level
Description
All component inputs must be lists with a data array
[nl x nw x nt] and matching lon, lat, time.
Usage
.compute_aci_grid(
comp_t_high,
comp_t_low,
comp_prec,
comp_drought,
comp_wind,
comp_sl = NULL,
col_high = "t90",
col_low = "t10"
)
Arguments
comp_t_high |
Temperature high component (list with |
comp_t_low |
Temperature low component. |
comp_prec |
Precipitation component. |
comp_drought |
Drought component. |
comp_wind |
Wind component. |
comp_sl |
Sea-level component (list with |
col_high |
Column name for temperature high (e.g. |
col_low |
Column name for temperature low (e.g. |
Value
A list with arrays [nl x nw x nt] for each component and
ACI, plus lon, lat, time.
Compute monthly threshold-crossing frequency from daily extrema
Description
Shared helper behind calculate_halfday_component() (base-R) and
calculate_halfday_component_terra() (terra). Kept independent of
how daily_ext/thresholds_day were produced, so both loading
paths reuse the exact same, already-tested logic.
Usage
.crossing_frequency(daily_ext, thresholds_day, above_thresholds, lon, lat)
Arguments
daily_ext |
List with |
thresholds_day |
Array |
above_thresholds |
Logical. |
lon, lat |
Coordinate vectors, carried through to the output. |
Value
A list with data [lon x lat x months] and monthly
time.
Binary threshold-crossing from an already-daily wind power series
Description
Shared helper, see .wind_thresholds_from_wp().
Usage
.days_above_from_wp(wp, thr, lon, lat)
Convert an ISO-3 country code to its English name for rnaturalearth
Description
Internal helper, kept for backward compatibility. As of the GADM-based
.load_admin_sf(), administrative polygons are no longer fetched
via rnaturalearth::ne_states() (which only exposes ONE fixed
administrative level per country, ignoring admin_level), so this
lookup is no longer used internally for that purpose. ne_coastline()
(a separate, level-independent worldwide coastline layer used in
assign_sealevel_to_admin()) does not need it either.
Usage
.iso3_to_country_name(iso3)
Arguments
iso3 |
A single ISO-3 character string (case-insensitive). |
Value
The corresponding English country name.
Load administrative boundary polygons for a country, at a given level
Description
Replaces the former rnaturalearth::ne_states()-based approach,
which only ever exposed a single fixed administrative level per country
(so admin_level had no real effect downstream, regardless of the
value supplied). Uses GADM (via geodata::gadm()), which provides a
genuine multi-level administrative hierarchy for virtually every country
(level 0 = national boundary, level 1 = states/regions, level 2 =
departments/counties, etc., depending on how finely each country is
subdivided in GADM).
Usage
.load_admin_sf(country_abbrev, admin_level = 1, cache_dir = .gadm_cache_dir())
Arguments
country_abbrev |
ISO-3 country code (e.g. |
admin_level |
Integer >= 0. |
cache_dir |
Directory used to cache the downloaded GADM data. Default: a persistent per-user cache directory. |
Details
GADM keys countries directly by their ISO-3 code, so no name-lookup
table is needed (unlike rnaturalearth::ne_states(), which expected
English country names and required maintaining .iso3_to_ne_name).
Downloads are cached on disk (cache_dir, by default a persistent
per-user cache via tools::R_user_dir()), so repeated calls for the
same country/level across build_admin_mask(),
assign_sealevel_to_admin(), and the plotting helpers do not
re-download the data.
Value
An sf object with columns name (administrative
unit name at the requested level) and geometry, in EPSG:4326.
Compute annual max consecutive dry days from an already-daily series
Description
Shared helper behind max_consecutive_dry_days() (base-R) and its
terra equivalent. Operates exclusively on DAILY-resolution precipitation
totals (small, even for 40+ years of data).
Usage
.max_consecutive_dry_days_from_daily(daily)
Arguments
daily |
List |
Value
A list with data [lon x lat x years] and annual time.
Compute monthly max rolling precipitation from an already-daily series
Description
Shared helper behind calculate_maximum_precipitation_over_window()
(base-R) and its terra equivalent. Operates exclusively on DAILY-resolution
precipitation totals (small, even for 40+ years of data).
Usage
.max_precipitation_from_daily(daily, var_name, window_size)
Arguments
daily |
List |
var_name |
Passed through to |
window_size |
Rolling window in days. |
Value
A list with data [lon x lat x months] and time.
Merge multiple yearly NetCDF files along the time dimension
Description
Merge multiple yearly NetCDF files along the time dimension
Usage
.merge_netcdf_files(files, output, variable)
Arguments
files |
Character vector of NetCDF paths. |
output |
Output NetCDF file. |
variable |
Variable name. |
Monthly frequency of a binary daily series
Description
Shared helper, see .wind_thresholds_from_wp().
Usage
.monthly_frequency_from_binary(bin, lon, lat)
Rename the ERA5 land-sea mask variable to 'country' and drop the time dim
Description
Rename the ERA5 land-sea mask variable to 'country' and drop the time dim
Usage
.rename_mask_variable(raw_file, mask_file)
Resolve a caching/output directory, defaulting to a session tempdir()
Description
CRAN policy forbids writing to the user's home filespace (including the
package directory and getwd()) by default. All save_dir,
load_dir, sealevel_dir and dest_dir arguments across
the package therefore default to NULL, and are resolved here to a
sub-directory of tempdir() when the user does not supply an
explicit path. Users who want persistent caching across sessions should
pass their own directory explicitly.
Usage
.resolve_cache_dir(dir, subdir = NULL)
Arguments
dir |
Character or |
subdir |
Character or |
Value
Character. The resolved directory path.
Resolve which component functions to use based on the compute engine
Description
Isolates the engine dispatch logic used by calculate_aci()
so it can be unit-tested directly (via expect_identical()) without
needing to mock or run the full calculate_aci() pipeline.
Usage
.resolve_component_functions(engine = c("base", "terra"))
Arguments
engine |
|
Value
A list with elements temperature, wind,
drought, precipitation, each a function with the same
signature as its base-R counterpart.
Reorient a terra array to the package's [lon x lat x layer] convention
Description
terra::as.array() returns [nrow x ncol x nlyr] with rows
(latitude) in decreasing order. The rest of the package expects
[lon x lat x layer] with latitude increasing, matching
load_netcdf(). Shared by .spatraster_to_list() and by
calculate_percentiles_terra()'s day-of-year output (which has no
real time dimension, so .spatraster_to_list() doesn't apply).
Usage
.spatraster_to_array_only(r)
Arguments
r |
A |
Value
A numeric array [ncol x nrow x nlyr] = [lon x lat x layer].
Convert a (small) SpatRaster back to the package's plain-list format
Description
Once data has been reduced to daily (or coarser) resolution, it is small
enough to hand off to the rest of the existing base-R pipeline
(resample_monthly(), standardize_metric(),
.compute_aci_grid(), etc.) unchanged. This is the bridge between the
terra-based loading/reduction steps and that pipeline.
Usage
.spatraster_to_list(r)
Arguments
r |
A |
Value
A list with elements data ([lon x lat x time] array),
lon, lat, time – the same structure produced by
load_netcdf().
Compute per-day-of-year wind power thresholds from an already-daily series
Description
Shared helper behind wind_thresholds() (base-R) and the terra
pipeline (wind_power_terra() + this same function). Operates
exclusively on DAILY-resolution wind power (already small, even for
40+ years of data), never on raw hourly arrays.
Usage
.wind_thresholds_from_wp(wp, reference_period, lon, lat)
Arguments
wp |
A list |
reference_period |
Character vector |
lon, lat |
Coordinate vectors, carried through to the output. |
Value
A list with data [lon x lat x all_days] and time.
Concatenate two 3-D arrays along the third dimension (time)
Description
Concatenate two 3-D arrays along the third dimension (time)
Usage
abind_time(a, b)
Actuarial Climate Index (ACI)
Description
Computes the full Actuarial Climate Index by combining all five components: temperature (T90 and T10), precipitation, drought, wind, and sea level.
Aggregate a monthly data frame to a given temporal granularity
Description
Aggregate a monthly data frame to a given temporal granularity
Usage
aggregate_granularity(df, granularity = "month")
Arguments
df |
A data.frame with "YYYY-MM-01" Date row names (monthly). |
granularity |
One of "month", "season", "semester", "year". |
Value
A data.frame with aggregated values and appropriate row names.
Animate the ACI or a component over time
Description
Produces a GIF animation (via gganimate) showing the evolution of a spatial variable at each time step. Requires gganimate and gifski (or png) to be installed.
Usage
animate_aci_map(
data,
variable = "ACI",
country_abbrev = NULL,
admin_level = NULL,
crs_metric = 4326,
var_label = "Standardised anomaly",
title = "ACI over time",
palette = "RdBu",
reverse = TRUE,
n_breaks = 9,
borders = TRUE,
fps = 4,
width = 800,
height = 600,
save_path = NULL
)
Arguments
data |
Grid-cell list or admin |
variable |
Variable to animate. Default |
country_abbrev |
Three-letter ISO code. |
admin_level |
Integer or |
crs_metric |
EPSG code, used for admin choropleth projection only.
Default |
var_label |
Colour-bar label. Default |
title |
Plot title. Default |
palette |
RColorBrewer palette. Default |
reverse |
Logical. Default |
n_breaks |
Integer. Default |
borders |
Logical. Default |
fps |
Frames per second. Default |
width |
Output width in pixels. Default |
height |
Output height in pixels. Default |
save_path |
File path for the output GIF. If |
Value
A gganimate animation object (invisibly).
Why dontrun
This example is wrapped in dontrun because it depends on the
optional gganimate and gifski packages (declared in
Suggests, not guaranteed to be installed on every machine
running R CMD check), and because rendering a multi-frame GIF
takes well over 5 seconds, making it unsuitable for donttest as
well.
Examples
## Not run:
lon <- seq(-5, 8, length.out = 10)
lat <- seq(42, 51, length.out = 8)
arr <- array(stats::rnorm(10 * 8 * 5), dim = c(10, 8, 5))
grid <- list(ACI = arr, lon = lon, lat = lat,
time = seq_len(5))
animate_aci_map(grid, variable = "ACI", country_abbrev = "FRA",
fps = 2, save_path = file.path(tempdir(), "aci_animation.gif"))
## End(Not run)
Apply a country mask to a NetCDF data array
Description
Sets grid cells to NA where the mask value is below threshold.
Usage
apply_mask(dataset, mask_path, var_name, threshold = 0.8)
Arguments
dataset |
List returned by |
mask_path |
Path to the mask NetCDF file (variable: |
var_name |
Name of the variable inside |
threshold |
Numeric threshold; cells with mask < threshold become NA. Default 0.8. |
Value
The dataset list with data masked in-place.
Apply a country mask to a SpatRaster
Description
Equivalent of apply_mask(): sets cells to NA where the mask
value is below threshold. Processed block-by-block by terra.
Usage
apply_mask_terra(r, mask_path, threshold = 0.8, chunk_size = 20000)
Arguments
r |
A |
mask_path |
Path to the mask NetCDF file (variable: |
threshold |
Numeric threshold. Default |
chunk_size |
Nombre max de couches traitees par bloc quand
|
Details
Note sur la limite de 65535 couches : le format interne utilise
par terra::mask() pour ecrire son resultat sur disque (fichier
temporaire) ne supporte pas plus de 65535 couches en sortie. Au-dela (cas
frequent en donnees horaires sur plusieurs decennies : ~300k couches pour
35 ans), on ne peut pas masquer l'objet en un seul appel. Cette fonction
bascule donc automatiquement sur un traitement par blocs temporels
('chunk_size' couches a la fois), ecrits en GeoTIFF (BigTIFF) puis
recombines en une seule source multi-fichiers, sans jamais materialiser
l'ensemble en RAM. Le masque etant purement spatial (identique a chaque
pas de temps), le decoupage en blocs ne change pas le resultat : un pixel
exclu par le masque l'est de la meme facon dans chaque bloc.
Value
The masked terra::SpatRaster.
Assign PSMSL tide-gauge stations to administrative units and compute coastal factors
Description
Performs a spatial join between PSMSL station coordinates and administrative
unit polygons, and computes for each unit the fraction of its perimeter
that is coastline. The coastline layer is cropped to the country bounding
box before intersection to speed up computation. All geometries are
projected to crs_metric before length calculations to ensure
results are in metres.
Usage
assign_sealevel_to_admin(country_abbrev, admin_level = 1, crs_metric = 4326)
Arguments
country_abbrev |
ISO-3 country code (e.g. |
admin_level |
Integer >= 0. Administrative level fetched via
GADM (see |
crs_metric |
Integer. EPSG code of a metric CRS appropriate for
the country, used for accurate length calculations. Default |
Value
A list with two elements:
station_idsNamed list: keys are administrative unit names, values are integer vectors of PSMSL station IDs within that unit.
factorsNamed numeric vector: keys are administrative unit names, values are the coastal fraction (coastline length / total perimeter) in
[0, 1]. Zero for landlocked units.
Build a spatial weight matrix mapping ERA5 grid cells to administrative units
Description
For each ERA5 grid cell, computes the fraction of its surface area that
falls within each administrative unit polygon (using sf geometry
intersection). All geometries are projected to crs_metric before
area calculations to ensure results are in metres squared.
The result can be computationally expensive for fine grids and large
countries — consider caching it with saveRDS().
Usage
build_admin_mask(
lon,
lat,
country_abbrev,
admin_level = 1,
resolution = 0.25,
crs_metric = 4326,
cache_dir = .gadm_cache_dir()
)
Arguments
lon |
Numeric vector of ERA5 longitudes. |
lat |
Numeric vector of ERA5 latitudes. |
country_abbrev |
ISO-3 country code (e.g. |
admin_level |
Integer >= 0. Administrative level fetched via GADM:
|
resolution |
Numeric. Half-width of ERA5 grid cells in degrees.
Default |
crs_metric |
Integer. EPSG code of a metric CRS appropriate for
the country, used for accurate area calculations. Default |
cache_dir |
Directory used to cache the downloaded GADM
administrative boundaries. Default: a persistent per-user cache
directory (see |
Value
A list with elements:
weightsA named list of length
length(lon) * length(lat). Each element is a named numeric vector of (unit -> fractional area weight) pairs.unitsCharacter vector of all administrative unit names.
lonInput longitudes.
latInput latitudes.
Calculate the Actuarial Climate Index
Description
This is the main entry point of the package. It instantiates all five climate components, standardises them over the reference period, and combines them into a single ACI time series:
Usage
calculate_aci(
country_abbrev,
study_period,
reference_period,
years = NULL,
temperature_data_path = NULL,
precipitation_data_path = NULL,
wind_u10_data_path = NULL,
wind_v10_data_path = NULL,
mask_data_path = NULL,
sealevel_dir = NULL,
percentile_high = 90,
percentile_low = 10,
granularity = "month",
area = TRUE,
factor = 1/5,
max_dist_km = 500,
admin_level = NULL,
crs_metric = 4326,
save = FALSE,
save_dir = NULL,
load_dir = NULL,
computed_components = FALSE,
engine = c("base", "terra"),
cores = 1L
)
Arguments
country_abbrev |
Three-letter ISO 3166-1 alpha-3 country code
(e.g. |
study_period |
Character vector of length 2:
|
reference_period |
Character vector of length 2:
|
years |
Integer vector of years covered by the NetCDF files
(e.g. |
temperature_data_path |
Path to the hourly 2-m temperature NetCDF
( |
precipitation_data_path |
Path to the precipitation NetCDF
( |
wind_u10_data_path |
Path to the u-component wind NetCDF
( |
wind_v10_data_path |
Path to the v-component wind NetCDF
( |
mask_data_path |
Path to the country mask NetCDF
( |
sealevel_dir |
Character or |
percentile_high |
Numeric. Upper percentile used for the hot temperature
component. Default |
percentile_low |
Numeric. Lower percentile used for the cold temperature
component. Default |
granularity |
Temporal aggregation level. One of
|
area |
Logical. Only used when |
factor |
Numeric in |
max_dist_km |
Numeric. Maximum distance (km) from a tide-gauge station
for a grid cell to receive a sea-level signal. Cells beyond this threshold
receive |
admin_level |
Integer or |
crs_metric |
Integer. EPSG code of a metric CRS
appropriate for the country, used for accurate area and length
calculations in |
save |
Logical. If |
save_dir |
Character. Directory for the cached |
load_dir |
Character. Directory from which to reload previously saved
|
computed_components |
Logical. If |
engine |
Character. |
cores |
Positive integer, default |
Details
ACI = \frac{T_{high} - T_{low} + P + D + \alpha \cdot SL + W}{5 + \alpha}
where \alpha is the sea-level erosion factor (coastal fraction,
default 1/5). For administrative units without coastal stations,
\alpha = 0 and the denominator becomes 5. At grid-cell level,
\alpha \in \{0, 1\} depending on whether the cell lies within
max_dist_km of a tide-gauge station.
Value
- National scalar (
area = TRUE,admin_level = NULL) -
A
data.framewith columnst<percentile_high>,t<percentile_low>,precipitation,drought,wind,sealevel, andACI, indexed by dates at the chosen granularity. - Grid-cell (
area = FALSE,admin_level = NULL) -
A named list with one array
[lon x lat x nt]per component (ACI,t<percentile_high>,t<percentile_low>,precipitation,drought,wind,sealevel), pluslon,lat, andtime(character vector of period labels at the chosen granularity). - Administrative (
admin_levelinteger) -
A
data.frameindexed by dates at the chosen granularity, with one<component>_<unit>column per administrative unit FOR EACH component (ACI,t<percentile_high>,t<percentile_low>,precipitation,drought,wind,sealevel) – e.g.ACI_<unit>,t90_<unit>,precipitation_<unit>, etc. This mirrors the grid-cell mode's per-component structure, and letsplot_aci_map()plot any individual component at admin level, not justACIitself.
Examples
The four examples below all require real ERA5 NetCDF files (temperature,
precipitation, wind, country mask), obtained beforehand via
download_era5/download_mask and a Copernicus
CDS API key (see cds_set_key). They cannot be run
automatically by R CMD check and are therefore wrapped in
dontrun: (1) national ACI at annual granularity; (2) grid-cell
ACI (full spatial output); (3) ACI with custom percentiles (T95/T5); and
(4) ACI by department (admin level 2), using Lambert-93 for France.
Examples
## Not run:
result <- calculate_aci(
temperature_data_path = "t2m_1960-2020.nc",
precipitation_data_path = "tp_1960-2020.nc",
wind_u10_data_path = "u10_1960-2020.nc",
wind_v10_data_path = "v10_1960-2020.nc",
country_abbrev = "FRA",
mask_data_path = "mask_FRA.nc",
study_period = c("1980-01-01", "2020-12-31"),
reference_period = c("1961-01-01", "1990-12-31"),
granularity = "year",
area = TRUE,
factor = 1/5
)
grid <- calculate_aci(
temperature_data_path = "t2m_1960-2020.nc",
precipitation_data_path = "tp_1960-2020.nc",
wind_u10_data_path = "u10_1960-2020.nc",
wind_v10_data_path = "v10_1960-2020.nc",
country_abbrev = "FRA",
mask_data_path = "mask_FRA.nc",
study_period = c("1980-01-01", "2020-12-31"),
reference_period = c("1961-01-01", "1990-12-31"),
granularity = "year",
area = FALSE,
max_dist_km = 500
)
result_custom <- calculate_aci(
temperature_data_path = "t2m_1960-2020.nc",
precipitation_data_path = "tp_1960-2020.nc",
wind_u10_data_path = "u10_1960-2020.nc",
wind_v10_data_path = "v10_1960-2020.nc",
country_abbrev = "FRA",
mask_data_path = "mask_FRA.nc",
study_period = c("1980-01-01", "2020-12-31"),
reference_period = c("1961-01-01", "1990-12-31"),
granularity = "year",
percentile_high = 95,
percentile_low = 5
)
result_dept <- calculate_aci(
temperature_data_path = "t2m_1960-2020.nc",
precipitation_data_path = "tp_1960-2020.nc",
wind_u10_data_path = "u10_1960-2020.nc",
wind_v10_data_path = "v10_1960-2020.nc",
country_abbrev = "FRA",
mask_data_path = "mask_FRA.nc",
study_period = c("1980-01-01", "2020-12-31"),
reference_period = c("1961-01-01", "1990-12-31"),
granularity = "year",
area = FALSE,
admin_level = 2,
crs_metric = 2154
)
## End(Not run)
Calculate the half-day (day or night) temperature component
Description
Calculate the half-day (day or night) temperature component
Usage
calculate_halfday_component(
dataset,
reference_period,
part_of_day,
extremum,
percentile,
above_thresholds
)
Arguments
dataset |
Full sub-daily |
reference_period |
Character vector |
part_of_day |
|
extremum |
|
percentile |
Numeric percentile (e.g. 90 or 10). |
above_thresholds |
Logical. |
Value
A list with data [lon × lat × months] and monthly time.
Calculate the half-day (day or night) temperature component (terra version)
Description
Calculate the half-day (day or night) temperature component (terra version)
Usage
calculate_halfday_component_terra(
r,
reference_period,
part_of_day,
extremum,
percentile,
above_thresholds,
mask_path = NULL,
threshold = 0.8,
cores = 1L
)
Arguments
r |
A |
reference_period |
Character vector |
part_of_day |
|
extremum |
|
percentile |
Numeric percentile (e.g. 90 or 10). |
above_thresholds |
Logical. |
mask_path |
Path to the mask NetCDF file, or |
threshold |
Numeric threshold for the mask. Default |
cores |
Passed to |
Value
Same structure as calculate_halfday_component():
list(data, time, lon, lat).
Calculate maximum precipitation over a rolling window
Description
Computes the rolling window_size-day sum of precipitation, then
takes the monthly maximum.
Usage
calculate_maximum_precipitation_over_window(
dataset,
var_name = "tp",
window_size = 5L
)
Arguments
dataset |
List returned by |
var_name |
Variable name in |
window_size |
Rolling window in DAYS. Default |
Value
A list with data [lon x lat x months] and time.
Calculate maximum precipitation over a rolling window (terra version)
Description
Calculate maximum precipitation over a rolling window (terra version)
Usage
calculate_maximum_precipitation_over_window_terra(
r,
var_name = "tp",
window_size = 5L,
mask_path = NULL,
threshold = 0.8
)
Arguments
r |
A |
var_name |
Variable name in |
window_size |
Rolling window in DAYS. Default |
mask_path |
Path to the mask NetCDF file, or |
threshold |
Numeric threshold for the mask. Default |
Value
Same structure as calculate_maximum_precipitation_over_window().
Compute temperature percentile thresholds for each day of year
Description
Uses a rolling window over the reference period followed by a group by day-of-year percentile.
Usage
calculate_percentiles(dataset, n, reference_period, part_of_day)
Arguments
dataset |
Full sub-daily |
n |
Percentile (e.g. 90 or 10). |
reference_period |
Character vector |
part_of_day |
|
Value
A named numeric vector of length 366 (day-of-year 1–366).
Compute temperature percentile thresholds for each day of year (terra version)
Description
Equivalent of calculate_percentiles(). More experimental than
the other functions in this file: it relies on terra::roll() for
the rolling-window quantile, whose exact argument names have changed across
terra versions – check ?terra::roll against your installed version
(packageVersion("terra")) and validate on a small subset before
running on the full 40-year series.
Usage
calculate_percentiles_terra(
r,
n,
reference_period,
part_of_day,
filename = "",
cores = 1L
)
Arguments
r |
A |
n |
Percentile (e.g. 90 or 10). |
reference_period |
Character vector |
part_of_day |
|
filename |
Optional output path for the final thresholds. |
cores |
How many spatial tiles to process IN PARALLEL (a ceiling,
further capped by |
Details
Performance AND memory note: the rolling-window quantile
(terra::roll()) is by far the most expensive step of the whole
*_terra pipeline – it invokes a custom R callback
(stats::quantile()) at every timestep of reference_period
(filtered to day/night hours), for every cell. Crucially, a
single terra::roll() call over a whole country's grid can crash R
from memory pressure alone, with NO parallelism involved – observed
empirically even with cores = 1 on a 16GB machine, for a France-wide
grid with 13 years of reference data filtered to daytime hours
(window_size = 80). Because of this, the raster is now ALWAYS
split into small spatial tiles sized to a conservative, fixed memory
target (see target_tile_gb in
.calculate_percentiles_terra_tiled()), regardless of cores
– cores only controls how many of those already-memory-safe tiles
run concurrently (default 1: one at a time). Unlike
terra::tapp(), terra::roll() has no built-in cores
argument in the terra version this package was tested against (1.7.65) –
there is no GPU path either (neither terra/GDAL nor base R ship a GPU
rolling-quantile primitive).
Value
A terra::SpatRaster with 366 layers (day-of-year 1-366).
Calculate monthly wind exceedance frequency
Description
Calculate monthly wind exceedance frequency
Usage
calculate_period_wind_exceedance_frequency(
u10_dataset,
v10_dataset,
reference_period
)
Arguments
u10_dataset |
List for |
v10_dataset |
List for |
reference_period |
Character vector |
Value
A list with data [lon x lat x periods] and time.
Calculate monthly wind exceedance frequency (terra version)
Description
Drop-in, memory-safe replacement for
calculate_period_wind_exceedance_frequency(). Only the initial
wind_power_terra() call differs from the base-R version; the
threshold, crossing, and monthly-aggregation steps reuse the exact same
helpers, since they already operate on small, daily-resolution data.
Usage
calculate_period_wind_exceedance_frequency_terra(
u10_r,
v10_r,
reference_period,
mask_path = NULL,
threshold = 0.8
)
Arguments
u10_r, v10_r |
|
reference_period |
Character vector |
mask_path |
Path to the mask NetCDF file, or |
threshold |
Numeric threshold for the mask. Default |
Value
Same as calculate_period_wind_exceedance_frequency().
Calculate the rolling sum of a climate variable
Description
Computes a rolling (sliding-window) sum along the time dimension of a 3-D climate array.
Usage
calculate_rolling_sum(dataset, var_name, window_size)
Arguments
dataset |
List returned by |
var_name |
Variable name (for documentation; the array in
|
window_size |
Integer number of time steps for the rolling window. |
Value
A list with the same structure as dataset but with
data replaced by the rolling sum (leading incomplete windows are
NA).
Set your CDS Personal Access Token
Description
Wrapper around wf_set_key for the new CDS API
(post-October 2024). The token is stored securely in the system keyring and
never needs to appear in your scripts again.
Usage
cds_set_key(token)
Arguments
token |
Character. Your CDS Personal Access Token (UUID format). |
Details
To obtain your token:
Create a free account at https://cds.climate.copernicus.eu.
Go to your profile → Personal Access Token.
Copy the token (a UUID string) and pass it to this function once.
Value
Invisibly NULL. The token is saved in the system keyring.
Examples
## Not run:
cds_set_key("xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx")
## End(Not run)
Base Climate Component Helpers
Description
Low-level helpers shared by all ACI component functions.
Terra-based Loading and Hourly-to-Daily Reduction
Description
Memory-safe alternatives to load_netcdf()/apply_mask()
and to the hourly-resolution steps of the temperature, precipitation and wind
pipelines (temp_extremum(), calculate_percentiles(), the daily
resampling inside wind_power()).
Why this file exists: for a whole country at hourly resolution
over 40+ years, ncdf4::ncvar_get() materialises the full
[lon x lat x time] array in RAM in one shot (tens of GB). terra
reads NetCDF lazily (via GDAL) and processes computations block-by-block,
writing results to disk instead of accumulating them in memory.
Only the hourly-scale steps are ported here. Once data has been reduced
to DAILY resolution (via resample_daily_terra(), temp_extremum_terra(), ...),
the resulting object is small enough (~40 years x 365 days) to convert back
to a plain array with .spatraster_to_list() and hand off, unchanged, to the
rest of the existing (already tested) pipeline – resample_monthly(),
standardize_metric(), .compute_aci_grid(), etc.
Calculate days with wind power above the 90th-percentile threshold
Description
Calculate days with wind power above the 90th-percentile threshold
Usage
days_above_wind_thresholds(u10_dataset, v10_dataset, reference_period)
Arguments
u10_dataset |
List for |
v10_dataset |
List for |
reference_period |
Character vector |
Value
A list with binary data [lon x lat x days] and time.
Download ERA5 and Country Mask Data
Description
Functions to download ERA5 climate variables and country mask from the Copernicus Climate Data Store (CDS) via the ecmwfr package (v2.0+, new CDS API — Personal Access Token only, no UID required).
Download an ERA5 variable from the Copernicus CDS
Description
Downloads hourly ERA5 single-level data for one variable and one or several years, for a given geographical bounding box. Files are downloaded year by year and then optionally merged into a single NetCDF using the ncdf4 package.
Usage
download_era5(
variable = c("t2m", "tp", "u10", "v10"),
years,
area = c(51.5, -5.5, 41, 10),
country_abbrev = NULL,
dest_dir = NULL,
merge = TRUE,
overwrite = FALSE
)
Arguments
variable |
Character. Short name of the ERA5 variable: one of
|
years |
Integer vector. Years to download (e.g. |
area |
Numeric vector of length 4: |
country_abbrev |
Character. Three-letter ISO 3166-1 alpha-3 country
code (e.g. |
dest_dir |
Character. Directory where files will be saved. If
|
merge |
Logical. If |
overwrite |
Logical. If |
Details
The CDS Personal Access Token must be stored beforehand with
cds_set_key.
Value
Invisibly, the path to the final NetCDF file (merged if
merge = TRUE, otherwise the directory containing yearly files).
Examples
## Not run:
# Store your token once
cds_set_key("xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx")
# Automatic path: <tempdir()>/xaci_era5/FRA/tp_1961_1990.nc
download_era5(
variable = "tp",
years = 1961:1990,
area = c(51.5, -5.5, 41.0, 10.0),
country_abbrev = "FRA"
)
# Or explicit path:
download_era5(
variable = "tp",
years = 1961:1990,
area = c(51.5, -5.5, 41.0, 10.0),
dest_dir = "my/custom/path"
)
## End(Not run)
Download all ERA5 variables required by the xaci package
Description
Convenience wrapper that calls download_era5 four times (one
per variable: t2m, tp, u10, v10).
Usage
download_era5_all(
years,
area = c(51.5, -5.5, 41, 10),
country_abbrev = NULL,
dest_dir = NULL,
merge = TRUE,
overwrite = FALSE
)
Arguments
years |
Integer vector of years to download. |
area |
Bounding box |
country_abbrev |
Character. ISO-3 country code (e.g. |
dest_dir |
Character. Output directory. If |
merge |
Logical. Merge yearly files. Default |
overwrite |
Logical. Overwrite existing files. Default |
Value
Invisibly, a named character vector of output paths (one per variable).
Examples
## Not run:
cds_set_key("xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx")
# Produces (by default): <tempdir()>/xaci_era5/FRA/t2m_1961_1990.nc, tp_..., u10_..., v10_...
download_era5_all(
years = 1961:1990,
area = c(51.5, -5.5, 41.0, 10.0),
country_abbrev = "FRA"
)
## End(Not run)
Download the country mask from the Copernicus CDS
Description
Downloads the ERA5 land-sea mask for the given bounding box, then rescales
it to [0, 1] and saves it as mask_<country_abbrev>.nc in
dest_dir. The mask variable is renamed to country so it is
directly compatible with apply_mask.
Usage
download_mask(
country_abbrev = "FRA",
area = c(51.5, -5.5, 41, 10),
dest_dir = NULL,
overwrite = FALSE
)
Arguments
country_abbrev |
Three-letter ISO 3166-1 alpha-3 country code
(e.g. |
area |
Numeric vector |
dest_dir |
Character. Directory for the output file.
Default |
overwrite |
Logical. Overwrite if the file already exists.
Default |
Value
Invisibly, the path to the mask NetCDF file.
Examples
## Not run:
cds_set_key("xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx")
# Produces (by default): <tempdir()>/xaci_era5/FRA/mask_FRA.nc
download_mask(
country_abbrev = "FRA",
area = c(51.5, -5.5, 41.0, 10.0)
)
## End(Not run)
Drought Component of the ACI
Description
Computes the drought component of the Actuarial Climate Index via maximum consecutive dry days (CDD).
Calculate the drought component of the ACI
Description
Computes standardised consecutive dry days.
Usage
drought_component(
precipitation_data_path,
country_abbrev,
reference_period,
study_period,
mask_path = NULL,
area = FALSE,
admin_level = NULL,
admin_mask = NULL,
crs_metric = 4326,
computed_components = FALSE,
save = FALSE,
save_dir = NULL,
load_dir = NULL
)
Arguments
precipitation_data_path |
Path to the precipitation NetCDF file. |
country_abbrev |
Three-letter ISO country code (e.g.
|
reference_period |
Character vector |
study_period |
Character vector |
mask_path |
Path to the country mask NetCDF file, or
|
area |
Logical. If |
admin_level |
Integer or |
admin_mask |
Output of |
crs_metric |
EPSG code for the metric CRS used when
building the admin mask. Default |
computed_components |
Logical. If |
save |
Logical. Default |
save_dir |
Character. Default |
load_dir |
Character. Default |
Value
Named numeric vector (area = TRUE), standardised list
(area = FALSE), or data.frame per admin unit.
Calculate the drought component of the ACI (terra version)
Description
Drop-in, memory-safe replacement for drought_component().
Usage
drought_component_terra(
precipitation_data_path,
country_abbrev,
reference_period,
study_period,
mask_path = NULL,
area = FALSE,
admin_level = NULL,
admin_mask = NULL,
crs_metric = 4326,
computed_components = FALSE,
save = FALSE,
save_dir = NULL,
load_dir = NULL
)
Arguments
precipitation_data_path |
Path to the precipitation NetCDF file. |
country_abbrev |
Three-letter ISO country code (e.g.
|
reference_period |
Character vector |
study_period |
Character vector |
mask_path |
Path to the country mask NetCDF file, or
|
area |
Logical. If |
admin_level |
Integer or |
admin_mask |
Output of |
crs_metric |
EPSG code for the metric CRS used when
building the admin mask. Default |
computed_components |
Logical. If |
save |
Logical. Default |
save_dir |
Character. Default |
load_dir |
Character. Default |
Value
Same as drought_component().
Linearly interpolate annual CDD to monthly resolution
Description
For each pair of consecutive years k and k+1 the monthly CDD
for month m \in 1..12 of year k is:
CDD_m = \frac{12-m}{12} \cdot CDD_k + \frac{m}{12} \cdot CDD_{k+1}
The last year repeats its own value for all 12 months.
Usage
drought_interpolate(cdd_annual)
Arguments
cdd_annual |
List returned by |
Value
A list with data [lon × lat × months] and monthly time.
Terra-based Drought Component
Description
Memory-safe equivalents of max_consecutive_dry_days()
and drought_component(). Only the hourly-to-daily reduction runs
through terra; drought_interpolate() and the consecutive-dry-day
scan already operate on small, annual/daily-resolution data, so they are
reused as-is via the shared helper
.max_consecutive_dry_days_from_daily() (defined in
drought.R) – no logic is duplicated.
Interpolate tide-gauge sea-level values onto an ERA5 grid using IDW
Description
Interpolate tide-gauge sea-level values onto an ERA5 grid using IDW
Usage
interpolate_sealevel_to_grid(raw, lon, lat, max_dist_km = 500, power = 2)
Arguments
raw |
List returned by |
lon |
Numeric vector of grid longitudes (length nl). |
lat |
Numeric vector of grid latitudes (length nw). |
max_dist_km |
Numeric. Cells farther than this from every station
receive |
power |
Numeric. IDW power parameter. Default |
Value
A list with data (array [nl x nw x nt]),
lon, lat, time (POSIXct).
Load a NetCDF dataset and optionally apply a country mask
Description
This function is a constructor.
It reads a NetCDF variable and, if mask_path is provided, zeroes out
(sets to NA) all grid cells where the mask value is below
threshold.
Usage
load_component(data_path, var_name, mask_path = NULL, threshold = 0.8)
Arguments
data_path |
Path to the NetCDF data file. |
var_name |
Name of the primary variable to load. |
mask_path |
Path to the mask NetCDF file, or |
threshold |
Numeric threshold for the mask. Default |
Value
A list with elements data (3-D array [lon × lat × time]),
lon, lat, time (POSIXct vector), and
var_name.
Load a NetCDF variable and optionally apply a country mask (terra version)
Description
Drop-in, memory-safe replacement for load_component() intended for
full-resolution, grid-cell-level ("area = FALSE") workflows over long
historical periods.
Usage
load_component_terra(
data_path,
var_name,
mask_path = NULL,
threshold = 0.8,
chunk_size = 20000
)
Arguments
data_path |
Path to the NetCDF file. |
var_name |
Name of the variable to extract. |
mask_path |
Path to the mask NetCDF file, or |
threshold |
Numeric threshold for the mask. Default |
chunk_size |
Passe a |
Value
A terra::SpatRaster.
Load a NetCDF variable as a 3D array [lon x lat x time]
Description
Load a NetCDF variable as a 3D array [lon x lat x time]
Usage
load_netcdf(path, var_name)
Arguments
path |
Path to the NetCDF file. |
var_name |
Name of the variable to extract. |
Value
A list with fields: data (3D array), lon, lat, time.
Lazily load a NetCDF variable as a terra SpatRaster
Description
Equivalent of load_netcdf(), but never materialises pixel values in
RAM: only metadata (dimensions, CRS, time) is read up front.
Usage
load_netcdf_terra(path, var_name)
Arguments
path |
Path to the NetCDF file. |
var_name |
Name of the variable to extract. |
Value
A terra::SpatRaster with one layer per time step and
terra::time() attached.
Load the bundled PSMSL station metadata
Description
Load the bundled PSMSL station metadata
Usage
load_psmsl_data()
Value
A data.frame of PSMSL tide-gauge station information.
Calculate maximum consecutive dry days (CDD) per year
Description
A dry day is defined as total daily precipitation < 1 mm. The function returns the annual maximum number of consecutive dry days for each grid cell.
Usage
max_consecutive_dry_days(dataset)
Arguments
dataset |
List returned by |
Value
A list with data [lon × lat × years] and annual time.
Calculate maximum consecutive dry days (terra version)
Description
Calculate maximum consecutive dry days (terra version)
Usage
max_consecutive_dry_days_terra(r, mask_path = NULL, threshold = 0.8)
Arguments
r |
A |
mask_path |
Path to the mask NetCDF file, or |
threshold |
Numeric threshold for the mask. Default |
Value
Same structure as max_consecutive_dry_days().
Merge a list of data frames on their row-name index
Description
Merge a list of data frames on their row-name index
Usage
merge_dataframes(dataframes)
Arguments
dataframes |
A list of |
Value
A single merged data.frame.
Plot the ACI component decomposition
Description
Produces either a bar chart (one panel per component,
type = "bar") or a stacked area chart
(type = "stacked") showing the six standardised components that
make up the ACI.
Usage
plot_aci_components(
aci_df,
type = c("stacked", "line", "bar"),
components = NULL,
title = "ACI Component Contributions",
subtitle = NULL
)
Arguments
aci_df |
A |
type |
|
components |
Character vector of component names to include.
Default: all six |
title |
Plot title. |
subtitle |
Character or |
Value
A ggplot object.
Examples
# Toy monthly ACI data.frame (see plot_aci_timeseries() for details)
n <- 60L
dates <- format(seq(as.Date("2015-01-01"), by = "month", length.out = n),
"%Y-%m")
aci_df <- data.frame(
t90 = 20 + stats::rnorm(n, sd = 2),
t10 = 5 + stats::rnorm(n, sd = 2),
precipitation = stats::rnorm(n, sd = 1),
drought = stats::rnorm(n, sd = 1),
wind = stats::rnorm(n, sd = 1),
sealevel = stats::rnorm(n, sd = 1),
row.names = dates
)
aci_df$ACI <- with(aci_df, (t90 - t10 + precipitation + drought +
wind + sealevel) / 5)
plot_aci_components(aci_df, type = "bar")
plot_aci_components(aci_df, type = "stacked", components = c("t90", "t10"))
Plot a summary dashboard of the ACI results
Description
Arranges the four core plots (time series, component facets, boxplots and density) into a single patchwork figure. Requires the patchwork package to be installed.
Usage
plot_aci_dashboard(aci_df, title = "ACI Summary Dashboard")
Arguments
aci_df |
A |
title |
Overall figure title. Default |
Value
A patchwork object (inherits from ggplot).
Examples
# Toy monthly ACI data.frame (see plot_aci_timeseries() for details)
n <- 60L
dates <- format(seq(as.Date("2015-01-01"), by = "month", length.out = n),
"%Y-%m")
aci_df <- data.frame(
t90 = 20 + stats::rnorm(n, sd = 2),
t10 = 5 + stats::rnorm(n, sd = 2),
precipitation = stats::rnorm(n, sd = 1),
drought = stats::rnorm(n, sd = 1),
wind = stats::rnorm(n, sd = 1),
sealevel = stats::rnorm(n, sd = 1),
row.names = dates
)
aci_df$ACI <- with(aci_df, (t90 - t10 + precipitation + drought +
wind + sealevel) / 5)
plot_aci_dashboard(aci_df)
Plot the distribution of ACI components
Description
Displays the statistical distribution of each standardised component (and
optionally the global ACI) as boxplots (type = "boxplot"),
violin plots (type = "violin"), or
density curves (type = "density").
Usage
plot_aci_distribution(
aci_df,
components = NULL,
include_aci = FALSE,
type = c("boxplot", "violin", "density"),
title = "ACI Component Distributions",
subtitle = NULL
)
Arguments
aci_df |
A |
components |
Character vector of component columns to include. |
include_aci |
Logical. If |
type |
|
title |
Plot title. |
subtitle |
Character or |
Value
A ggplot object.
Examples
# Toy monthly ACI data.frame (see plot_aci_timeseries() for details)
n <- 60L
dates <- format(seq(as.Date("2015-01-01"), by = "month", length.out = n),
"%Y-%m")
aci_df <- data.frame(
t90 = 20 + stats::rnorm(n, sd = 2),
t10 = 5 + stats::rnorm(n, sd = 2),
precipitation = stats::rnorm(n, sd = 1),
drought = stats::rnorm(n, sd = 1),
wind = stats::rnorm(n, sd = 1),
sealevel = stats::rnorm(n, sd = 1),
row.names = dates
)
aci_df$ACI <- with(aci_df, (t90 - t10 + precipitation + drought +
wind + sealevel) / 5)
plot_aci_distribution(aci_df, type = "violin")
plot_aci_distribution(aci_df, type = "density")
Plot a spatial map of the ACI or one of its components
Description
Handles three types of input, at any spatial aggregation level produced
by calculate_aci() (grid-cell, admin level 1, admin level 2, ...):
-
Bare array (e.g.
grid$t90,grid$ACI): a single component array as stored in the grid-cell list returned bycalculate_aci(area = FALSE). Self-describing via its attachedlon/lat/time/country_abbrevattributes, so it can be passed on its own. Renders a raster map. SinceACIand its components share the exact same array structure, this works identically whethervariableis a component or the ACI itself. -
Grid-cell list (the full output of
calculate_aci(area = FALSE), or ofload_component()):variableselects which field of the list to map. Renders a raster map. -
Administrative
data.frame(output ofcalculate_aci(admin_level = N)): renders a choropleth map.country_abbrev/admin_level/crs_metricare read from the data.frame's attributes when not supplied explicitly.
Usage
plot_aci_map(
data,
variable = "ACI",
time_index = "mean",
country_abbrev = NULL,
admin_level = NULL,
crs_metric = NULL,
var_label = "Standardised anomaly",
title = "ACI Spatial Distribution",
palette = "RdBu",
reverse = TRUE,
n_breaks = 9,
borders = TRUE
)
Arguments
data |
A bare array (component or ACI, with attributes), a
named list (grid-cell / raw dataset), or a |
variable |
Name of the variable to map when |
time_index |
Integer (1-based time slice) or |
country_abbrev |
Three-letter ISO code. Required for admin maps and
for overlaying country/region borders on raster maps. If |
admin_level |
Integer or |
crs_metric |
EPSG code used for admin choropleth projection only.
If |
var_label |
Colour-bar label. Default |
title |
Plot title. Default |
palette |
RColorBrewer palette. Default |
reverse |
Logical. Reverse colour scale? Default |
n_breaks |
Number of colour breaks. Default |
borders |
Logical. Overlay administrative borders? Default
|
Value
A ggplot object.
Offline vs. online examples
The first two examples below use a small synthetic 10x8x5
(lon x lat x time) grid and run offline (borders = FALSE).
Overlaying administrative borders, or plotting an admin-level
choropleth, additionally requires downloading boundary polygons via
geodata::gadm() and therefore a working internet connection; the
corresponding examples are wrapped in dontrun and not run
automatically by R CMD check.
Examples
lon <- seq(-5, 8, length.out = 10)
lat <- seq(42, 51, length.out = 8)
arr <- array(stats::rnorm(10 * 8 * 5), dim = c(10, 8, 5))
arr <- structure(arr, lon = lon, lat = lat,
time = seq_len(5), country_abbrev = "FRA")
# Bare array, self-describing thanks to its attributes
plot_aci_map(arr, time_index = "mean", borders = FALSE)
# Equivalent, via the parent list and `variable`
grid <- list(t90 = arr, lon = lon, lat = lat, time = seq_len(5))
plot_aci_map(grid, variable = "t90", time_index = 1, borders = FALSE)
## Not run:
plot_aci_map(arr, time_index = "mean", country_abbrev = "FRA")
admin <- calculate_aci(
temperature_data_path = "t2m_1960-2020.nc",
precipitation_data_path = "tp_1960-2020.nc",
wind_u10_data_path = "u10_1960-2020.nc",
wind_v10_data_path = "v10_1960-2020.nc",
country_abbrev = "FRA",
mask_data_path = "mask_FRA.nc",
study_period = c("1961-01-01", "2020-12-31"),
reference_period = c("1961-01-01", "1990-12-31"),
granularity = "year",
area = FALSE,
admin_level = 1
)
plot_aci_map(admin, variable = "ACI", time_index = 1)
## End(Not run)
Plot the temporal mean of an ACI variable over a sub-period
Description
Convenience wrapper around plot_aci_map that computes the mean
over a user-defined date range rather than a single time index.
Usage
plot_aci_map_mean(
data,
variable = "ACI",
period = NULL,
country_abbrev = NULL,
admin_level = NULL,
crs_metric = NULL,
var_label = "Standardised anomaly",
title = NULL,
palette = "RdBu",
reverse = TRUE,
n_breaks = 9,
borders = TRUE
)
Arguments
data |
Bare array, grid-cell list, or admin |
variable |
Variable to map. Default |
period |
Character vector |
country_abbrev |
Three-letter ISO code. |
admin_level |
Integer or |
crs_metric |
EPSG code. Default |
var_label |
Colour-bar label. |
title |
Plot title. |
palette |
RColorBrewer palette. Default |
reverse |
Logical. Default |
n_breaks |
Integer. Default |
borders |
Logical. Default |
Value
A ggplot object.
Plot the ACI global time series
Description
Draws a line chart of the ACI values returned by
calculate_aci, with an optional smoothed
trend and a horizontal zero reference line.
Usage
plot_aci_timeseries(
aci_df,
smooth = TRUE,
span = 0.2,
title = "Actuarial Climate Index (ACI)",
colour = "#1F77B4",
fill_area = TRUE
)
Arguments
aci_df |
A |
smooth |
Logical. If |
span |
Numeric span for the LOESS smoother. Default |
title |
Plot title. Default |
colour |
Line colour for the raw ACI series.
Default |
fill_area |
Logical. If |
Value
A ggplot object.
Examples
# Toy monthly ACI data.frame (not from calculate_aci(), just for
# illustration), with the columns and "YYYY-MM" row names that
# calculate_aci(area = TRUE) would return.
n <- 60L
dates <- format(seq(as.Date("2015-01-01"), by = "month", length.out = n),
"%Y-%m")
aci_df <- data.frame(
t90 = 20 + stats::rnorm(n, sd = 2),
t10 = 5 + stats::rnorm(n, sd = 2),
precipitation = stats::rnorm(n, sd = 1),
drought = stats::rnorm(n, sd = 1),
wind = stats::rnorm(n, sd = 1),
sealevel = stats::rnorm(n, sd = 1),
row.names = dates
)
aci_df$ACI <- with(aci_df, (t90 - t10 + precipitation + drought +
wind + sealevel) / 5)
plot_aci_timeseries(aci_df)
Precipitation Component of the ACI
Description
Computes the precipitation component of the Actuarial Climate Index.
Calculate the precipitation component of the ACI
Description
Computes the standardised anomaly of maximum monthly precipitation over a rolling 5-day window.
Usage
precipitation_component(
precipitation_data_path,
country_abbrev,
reference_period,
study_period,
mask_path = NULL,
var_name = "tp",
window_size = 5L,
area = FALSE,
admin_level = NULL,
admin_mask = NULL,
crs_metric = 4326,
computed_components = FALSE,
save = FALSE,
save_dir = NULL,
load_dir = NULL
)
Arguments
precipitation_data_path |
Path to the precipitation NetCDF file. |
country_abbrev |
Three-letter ISO country code. |
reference_period |
Character vector |
study_period |
Character vector |
mask_path |
Path to the country mask NetCDF file, or
|
var_name |
Variable name in the NetCDF. Default
|
window_size |
Rolling window in days. Default |
area |
Logical. Default |
admin_level |
Integer or |
admin_mask |
Output of |
crs_metric |
EPSG code. Default |
computed_components |
Logical. Default |
save |
Logical. Default |
save_dir |
Character. Default |
load_dir |
Character. Default |
Value
Named numeric vector, standardised list, or data.frame
per admin unit.
Calculate the precipitation component of the ACI (terra version)
Description
Drop-in, memory-safe replacement for precipitation_component().
Usage
precipitation_component_terra(
precipitation_data_path,
country_abbrev,
reference_period,
study_period,
mask_path = NULL,
var_name = "tp",
window_size = 5L,
area = FALSE,
admin_level = NULL,
admin_mask = NULL,
crs_metric = 4326,
computed_components = FALSE,
save = FALSE,
save_dir = NULL,
load_dir = NULL
)
Arguments
precipitation_data_path |
Path to the precipitation NetCDF file. |
country_abbrev |
Three-letter ISO country code. |
reference_period |
Character vector |
study_period |
Character vector |
mask_path |
Path to the country mask NetCDF file, or
|
var_name |
Variable name in the NetCDF. Default
|
window_size |
Rolling window in days. Default |
area |
Logical. Default |
admin_level |
Integer or |
admin_mask |
Output of |
crs_metric |
EPSG code. Default |
computed_components |
Logical. Default |
save |
Logical. Default |
save_dir |
Character. Default |
load_dir |
Character. Default |
Value
Same as precipitation_component().
Terra-based Precipitation Component
Description
Memory-safe equivalents of
calculate_maximum_precipitation_over_window() and
precipitation_component(). Only the hourly-to-daily reduction
runs through terra; the rolling-sum and monthly-max logic already
operates on small, daily-resolution data, reused as-is via the shared
helper .max_precipitation_from_daily() (defined in
precipitation.R) – no logic is duplicated.
Reduce a standardised spatial metric to a data frame
Description
If admin_mask is NULL, averages over all non-NA cells
(national mean). Otherwise computes a weighted mean
per administrative unit using surface-fraction weights.
Usage
reduce_dataarray_to_dataframe(metric, column_name = "value", admin_mask = NULL)
Arguments
metric |
List with fields |
column_name |
Character. Column name prefix. Default |
admin_mask |
Output of |
Value
A data.frame with one column per administrative unit (or one
column for the national mean), indexed by month-start dates.
Reduce sea-level data to a single column or one column per administrative unit
Description
Reduce sea-level data to a single column or one column per administrative unit
Usage
reduce_sealevel_over_region(df, admin_assignment = NULL)
Arguments
df |
A |
admin_assignment |
Output of |
Value
A data.frame named "sealevel" (national) or
"sealevel_<unit>" (per admin unit). Units without coastal stations
have NA values.
Download PSMSL tide-gauge data for a country
Description
Reads the bundled psmsl_data.csv to identify stations for the given
country abbreviation, downloads the corresponding data files from the PSMSL
website, and stores them locally.
Usage
request_sealevel_data(country_abbrev, dest_dir = NULL)
Arguments
country_abbrev |
Three-letter ISO country code (e.g. |
dest_dir |
Destination directory. If |
Value
Invisibly, the path to the destination directory.
Resample a 3-D climate array to daily resolution
Description
Aggregates sub-daily data to daily values using the supplied function
(sum or mean).
Usage
resample_daily(dataset, FUN = sum)
Arguments
dataset |
List returned by |
FUN |
Aggregation function: |
Value
A new list with daily time and aggregated data.
Resample a SpatRaster to daily resolution (terra version)
Description
Equivalent of resample_daily(). Groups layers by calendar day and
applies fun, writing the result to disk chunk-by-chunk via
terra::tapp() rather than holding the full input in RAM.
Usage
resample_daily_terra(r, fun = "mean", filename = "")
Arguments
r |
A |
fun |
Aggregation function name understood by |
filename |
Optional path to write the result directly to disk (highly
recommended for large jobs). Default |
Value
A terra::SpatRaster with one layer per day.
Resample a 3-D or 1-D climate series to monthly resolution
Description
Applies FUN within each calendar month.
Usage
resample_monthly(dataset, FUN = mean)
Arguments
dataset |
List returned by |
FUN |
Aggregation function. Default |
Value
A list with data (monthly aggregates) and time
(first day of each month as POSIXct).
Sea Level Component of the ACI
Description
Processes PSMSL tide-gauge data and computes the sea-level component of the Actuarial Climate Index.
Replace PSMSL sentinel values (-99999) with NA
Description
Replace PSMSL sentinel values (-99999) with NA
Usage
sealevel_clean_data(df)
Arguments
df |
|
Value
Cleaned data.frame.
Calculate the sea-level component of the ACI
Description
Calculate the sea-level component of the ACI
Usage
sealevel_component(
country_abbrev,
study_period,
reference_period,
mask_path = NULL,
area = TRUE,
max_dist_km = 500,
sealevel_dir = NULL,
admin_level = NULL,
admin_assignment = NULL,
crs_metric = 4326,
computed_components = FALSE,
save = FALSE,
save_dir = NULL,
load_dir = NULL
)
Arguments
country_abbrev |
Three-letter country code (e.g. |
study_period |
Character vector |
reference_period |
Character vector |
mask_path |
Path to the country mask NetCDF. Used to extract the
ERA5 grid when |
area |
Logical. Mirrors the |
max_dist_km |
Numeric. Maximum distance (km) for IDW interpolation.
Only used when |
sealevel_dir |
Character or |
admin_level |
Integer or |
admin_assignment |
Output of |
crs_metric |
EPSG code used when building |
computed_components |
Logical. If |
save |
Logical. If |
save_dir |
Character. Directory for saving results.
Default |
load_dir |
Character. Directory from which to reload a cached result
when |
Value
If area = FALSE: a list with a [lon x lat x t] array,
lon, lat, time — same structure as other grid-cell
components. If area = TRUE: a data.frame of station
anomalies (national or per admin unit).
Compute monthly reference statistics for sea-level data
Description
Compute monthly reference statistics for sea-level data
Usage
sealevel_compute_monthly_stats(df, reference_period, stats)
Arguments
df |
Clean |
reference_period |
Character vector |
stats |
|
Value
A numeric matrix, 12 rows (calendar months "1"-"12"
as row names) x one column per station (station names as returned by
colnames(df)). Each station is standardised against its own
monthly reference statistics, independently of the other stations –
consistent with how the other ACI components (ERA5 grid cells,
administrative units) are each standardised against their own
reference, not a value pooled across the whole spatial domain.
Correct PSMSL float date format to Date objects
Description
PSMSL encodes dates as YYYY.fraction where the fraction
identifies the month.
Usage
sealevel_correct_date_format(df)
Arguments
df |
|
Value
The same data.frame with Date row names
("YYYY-MM-01"), rows with unrecognised dates removed.
Load sea-level txt files from a directory
Description
Load sea-level txt files from a directory
Usage
sealevel_load_data(directory)
Arguments
directory |
Path to the directory containing PSMSL |
Value
A data.frame with one column per station and a numeric date
as row names.
Load PSMSL station coordinates from the global station list CSV
Description
Reads the PSMSL station metadata CSV (columns: Station Name, ID, Lat., Lon., GLOSS ID, Country, Date, Coastline, Station) and returns coordinates for the requested stations.
Usage
sealevel_load_metadata(meta_path = NULL, station_ids = NULL)
Arguments
meta_path |
Optional explicit path to the CSV file. If |
station_ids |
Integer vector of PSMSL station IDs to keep. If
|
Value
A data.frame with columns station_id (character,
e.g. "Measurement_1"), lon, lat.
Full sea-level processing pipeline
Description
Full sea-level processing pipeline
Usage
sealevel_process(directory, study_period, reference_period)
Arguments
directory |
Path to the directory with PSMSL |
study_period |
Character vector |
reference_period |
Character vector |
Value
A named list with:
dataStandardised
data.frameof anomalies[time x stations], row names"YYYY-MM-DD".coordsA
data.framewith columnsstation_id,lon,lat, one row per station present indata.
Standardise sea-level data over the study period
Description
Standardise sea-level data over the study period
Usage
sealevel_standardize_data(df, monthly_means, monthly_std_devs, study_period)
Arguments
df |
Clean |
monthly_means |
Numeric matrix, 12 rows (months |
monthly_std_devs |
Same shape as |
study_period |
Character vector |
Value
A data.frame of standardised anomalies for the study period,
with rows containing all-NA removed. Each station's values are
standardised against its own monthly reference (see
sealevel_compute_monthly_stats()), not a value pooled across
stations.
Standardise a monthly metric relative to a reference period
Description
For each calendar month, computes the mean and standard deviation over the reference period, then returns (x - mean) / sd. Optionally averages over the spatial dimensions first.
Usage
standardize_metric(metric, reference_period, area = FALSE)
Arguments
metric |
A list with fields |
reference_period |
Character vector of length 2: start and end dates
( |
area |
Logical. If |
Value
If area = TRUE: a named numeric vector (names = dates).
Otherwise: a list with the same structure as metric but standardised
values.
Compute daily temperature extremum (min or max) for day or night hours
Description
Compute daily temperature extremum (min or max) for day or night hours
Usage
temp_extremum(dataset, extremum, period)
Arguments
dataset |
List returned by |
extremum |
|
period |
|
Value
A list with data [lon × lat × days] and daily time.
Compute daily temperature extremum (min or max) for day or night hours (terra version)
Description
Equivalent of temp_extremum(). Filters layers by hour-of-day (a
cheap, lazy operation on a SpatRaster – no data is read), then reduces to
daily resolution via resample_daily_terra().
Usage
temp_extremum_terra(r, extremum, period, filename = "")
Arguments
r |
A |
extremum |
|
period |
|
filename |
Optional output path (see |
Value
A terra::SpatRaster with one layer per day.
Temperature Component of the ACI
Description
Computes the temperature component of the Actuarial Climate Index.
Calculate the full temperature component of the ACI
Description
Combines day and night half-day components (equal weighting), then standardises relative to the reference period.
Usage
temperature_component(
temperature_data_path,
country_abbrev,
reference_period,
study_period,
mask_path = NULL,
percentile = 90,
extremum = "max",
above_thresholds = TRUE,
area = FALSE,
admin_level = NULL,
admin_mask = NULL,
crs_metric = 4326,
computed_components = FALSE,
save = FALSE,
save_dir = NULL,
load_dir = NULL
)
Arguments
temperature_data_path |
Path to the hourly |
country_abbrev |
Three-letter ISO country code. |
reference_period |
Character vector |
study_period |
Character vector |
mask_path |
Path to the country mask NetCDF file. |
percentile |
Percentile for the threshold. Default |
extremum |
|
above_thresholds |
Logical. Default |
area |
Logical. Default |
admin_level |
Integer or |
admin_mask |
Output of |
crs_metric |
EPSG code. Default |
computed_components |
Logical. Default |
save |
Logical. Default |
save_dir |
Character. Default |
load_dir |
Character. Default |
Value
Named numeric vector, standardised list, or data.frame
per admin unit.
Compute the temperature ACI component (terra version)
Description
Drop-in, memory-safe replacement for temperature_component(),
intended for full-resolution, grid-cell-level ("area = FALSE") workflows
over long historical periods (40+ years hourly).
Usage
temperature_component_terra(
temperature_data_path,
country_abbrev,
reference_period,
study_period,
mask_path = NULL,
percentile = 90,
extremum = "max",
above_thresholds = TRUE,
area = FALSE,
admin_level = NULL,
admin_mask = NULL,
crs_metric = 4326,
cores = 1L,
computed_components = FALSE,
save = FALSE,
save_dir = NULL,
load_dir = NULL
)
Arguments
temperature_data_path |
Path to the hourly |
country_abbrev |
Three-letter ISO country code. |
reference_period |
Character vector |
study_period |
Character vector |
mask_path |
Path to the country mask NetCDF file. |
percentile |
Percentile for the threshold. Default |
extremum |
|
above_thresholds |
Logical. Default |
area |
Logical. Default |
admin_level |
Integer or |
admin_mask |
Output of |
crs_metric |
EPSG code. Default |
cores |
Passed through to |
computed_components |
Logical. Default |
save |
Logical. Default |
save_dir |
Character. Default |
load_dir |
Character. Default |
Value
Same as temperature_component(): a standardized metric list,
or a data frame if admin_mask/admin_level is provided.
Terra-based Temperature Component
Description
Memory-safe equivalents of calculate_halfday_component()
and temperature_component(), for full-resolution, grid-cell-level
workflows over long historical periods (see R/component_terra.R
for the underlying loading/reduction primitives).
Only the hourly-scale steps (temp_extremum_terra(),
calculate_percentiles_terra()) run through terra. Once reduced to
daily/monthly resolution, the exact same .crossing_frequency()
helper used by the base-R pipeline takes over – no logic is duplicated.
Utility Functions for ACI Package
Description
Helper functions to manipulate and merge climate data.
Visualization Functions for the ACI Package
Description
A collection of ggplot2-based plotting functions to visualize the Actuarial Climate Index (ACI) and its components. Four families of plots are provided:
-
Time series of the global ACI (
plot_aci_timeseries) -
Component decomposition stacked / faceted chart (
plot_aci_components) -
Geographic maps from a NetCDF-derived array (
plot_aci_map) -
Distribution plots - boxplots and density ridges (
plot_aci_distribution)
Wind Component of the ACI
Description
Computes the wind component of the Actuarial Climate Index.
Calculate the wind component of the ACI
Description
Calculate the wind component of the ACI
Usage
wind_component(
wind_u10_data_path,
wind_v10_data_path,
country_abbrev,
reference_period,
study_period,
mask_path = NULL,
area = FALSE,
admin_level = NULL,
admin_mask = NULL,
crs_metric = 4326,
computed_components = FALSE,
save = FALSE,
save_dir = NULL,
load_dir = NULL
)
Arguments
wind_u10_data_path |
Path to the u10 NetCDF file. |
wind_v10_data_path |
Path to the v10 NetCDF file. |
country_abbrev |
Three-letter ISO country code. |
reference_period |
Character vector |
study_period |
Character vector |
mask_path |
Path to the country mask NetCDF file, or
|
area |
Logical. Default |
admin_level |
Integer or |
admin_mask |
Output of |
crs_metric |
EPSG code. Default |
computed_components |
Logical. Default |
save |
Logical. Default |
save_dir |
Character. Default |
load_dir |
Character. Default |
Value
Named numeric vector, standardised list, or data.frame
per admin unit.
Calculate the wind component of the ACI (terra version)
Description
Drop-in, memory-safe replacement for wind_component(), intended for
full-resolution, grid-cell-level ("area = FALSE") workflows over long
historical periods (40+ years hourly).
Usage
wind_component_terra(
wind_u10_data_path,
wind_v10_data_path,
country_abbrev,
reference_period,
study_period,
mask_path = NULL,
area = FALSE,
admin_level = NULL,
admin_mask = NULL,
crs_metric = 4326,
computed_components = FALSE,
save = FALSE,
save_dir = NULL,
load_dir = NULL
)
Arguments
wind_u10_data_path |
Path to the u10 NetCDF file. |
wind_v10_data_path |
Path to the v10 NetCDF file. |
country_abbrev |
Three-letter ISO country code. |
reference_period |
Character vector |
study_period |
Character vector |
mask_path |
Path to the country mask NetCDF file, or
|
area |
Logical. Default |
admin_level |
Integer or |
admin_mask |
Output of |
crs_metric |
EPSG code. Default |
computed_components |
Logical. Default |
save |
Logical. Default |
save_dir |
Character. Default |
load_dir |
Character. Default |
Value
Same as wind_component().
Calculate daily wind power from u10 and v10 components
Description
Wind speed = sqrt(u10^2 + v10^2), wind power = 0.5 * rho * ws^3.
Usage
wind_power(u10_dataset, v10_dataset, reference_period = NULL)
Arguments
u10_dataset |
List returned by |
v10_dataset |
List returned by |
reference_period |
Optional character vector |
Value
A list with data [lon x lat x days] (wind power in W/m²)
and daily time.
Calculate daily wind power from u10 and v10 components (terra version)
Description
Terra-based equivalent of wind_power(): computes daily mean u/v via
resample_daily_terra() (block-by-block, never loading the full
hourly cube in RAM), then wind speed/power arithmetic directly on the
(now daily, small) SpatRasters before converting back to the package's
list format.
Usage
wind_power_terra(
u10_r,
v10_r,
reference_period = NULL,
mask_path = NULL,
threshold = 0.8
)
Arguments
u10_r, v10_r |
|
reference_period |
Optional character vector |
mask_path |
Path to the mask NetCDF file, or |
threshold |
Numeric threshold for the mask. Default |
Value
Same structure as wind_power(): list(data, time, lon, lat).
Terra-based Wind Component
Description
Memory-safe equivalents of wind_power() and
wind_component(). Only wind_power_terra() touches raw
hourly data (via terra); wind_thresholds()'s internal logic,
threshold-crossing, and monthly aggregation already operate on DAILY
resolution data (small even for 40+ years), so they are reused as-is via
the shared helpers .wind_thresholds_from_wp(),
.days_above_from_wp(), .monthly_frequency_from_binary()
defined in wind.R – no logic is duplicated.
Calculate wind power thresholds (90th percentile per day-of-year)
Description
Calculate wind power thresholds (90th percentile per day-of-year)
Usage
wind_thresholds(u10_dataset, v10_dataset, reference_period)
Arguments
u10_dataset |
List for |
v10_dataset |
List for |
reference_period |
Character vector |
Value
A list with data [lon x lat x all_days] giving the threshold
for each day of the full series, and time.