| Type: | Package |
| Title: | Climate Change Vulnerability Assessment with Constrained Latent Models |
| Version: | 0.1.0 |
| Description: | A general framework for climate change vulnerability assessment (CCVA) of any species and any dataset. Variables are tagged as exposure, sensitivity or adaptive capacity; each component is computed from its own predictors by a chosen method; and the three components are combined into vulnerability. Methods range from the conventional weighted index of Ofori et al. (2017) <doi:10.1038/s41598-017-13245-y> to shape-constrained additive models ('scam'), latent-variable structural equation models ('lavaan') in which vulnerability is inferred from observable proxies, and penalised regression ('glmnet') for high-dimensional predictors. Ecological knowledge enters as explicit constraints on predictors, on each component's role and on the links between components. Diagnostics, validation against observed outcomes, bootstrap and weight-based uncertainty, calibrated risk predictions and plots for every step are included. |
| License: | GPL (≥ 3) |
| URL: | https://github.com/DoostiH/ccva |
| BugReports: | https://github.com/DoostiH/ccva/issues |
| Encoding: | UTF-8 |
| Depends: | R (≥ 4.1.0) |
| Imports: | ggplot2 (≥ 3.4.0), lavaan (≥ 0.6-12), stats, utils |
| Suggests: | scam, glmnet, knitr, rmarkdown, testthat (≥ 3.0.0) |
| VignetteBuilder: | knitr |
| Config/testthat/edition: | 3 |
| LazyData: | true |
| RoxygenNote: | 7.3.1 |
| NeedsCompilation: | no |
| Packaged: | 2026-10-14 06:45:01 UTC; MQ20173444 |
| Author: | Hassan Doosti [aut, cre, cph] (affiliation: Macquarie University) |
| Maintainer: | Hassan Doosti <hassan.doosti@mq.edu.au> |
| Repository: | CRAN |
| Date/Publication: | 2026-10-22 16:00:02 UTC |
ccva: Climate Change Vulnerability Assessment with Constrained Latent Models
Description
A general framework for climate change vulnerability assessment (CCVA). The workflow has four stages:
Details
1. **Data** – [as_ccva()] tags each variable of any dataset as an indicator of exposure, sensitivity or adaptive capacity, gives its direction, and names the observable outcomes (vulnerability proxies). [ccva_simulate()] generates data with a known latent structure. 2. **Components** – [ccva_exposure()], [ccva_sensitivity()] and [ccva_adaptive()] reduce each component's own predictors to a score (Ofori-style ordinal scoring, continuous mean, PCA or penalised regression for high-dimensional blocks such as genomic data). 3. **Vulnerability** – [ccva_combine()] combines the components with the weighted index of Ofori et al. (2017), a shape-constrained additive model, a latent-variable structural equation model, or a penalised two-stage model. Ecological knowledge enters through [ccva_constraints()]. [ccva()] runs the whole chain. 4. **Assessment** – [ccva_check()], [ccva_validate()], [ccva_compare()], [ccva_uncertainty()], [ccva_classify()], [ccva_rank()] and [ccva_plot()] diagnose, validate, quantify uncertainty and visualise every step.
Author(s)
Maintainer: Hassan Doosti hassan.doosti@mq.edu.au (Macquarie University) [copyright holder]
References
Ofori, B. Y., Stow, A. J., Baumgartner, J. B. and Beaumont, L. J. (2017). Influence of adaptive capacity on the outcome of climate change vulnerability assessment. *Scientific Reports*, 7, 12979.
Bollen, K. A. (1989). *Structural Equations with Latent Variables*. Wiley.
Pya, N. and Wood, S. N. (2015). Shape constrained additive models. *Statistics and Computing*, 25, 543–559.
See Also
Useful links:
Build a CCVA dataset
Description
Tags the columns of any data frame as indicators of the three CCVA components, gives each indicator a direction, and names the observable outcomes (vulnerability proxies such as IUCN status, population trend or range change). Every other function in the package works on the resulting ‘ccva_data' object, so this is the package’s data contract: nothing about a particular taxon or study is assumed.
Usage
as_ccva(
data,
exposure,
sensitivity,
adaptive = NULL,
outcomes = NULL,
id = NULL,
direction = NULL,
coords = NULL,
formative = NULL,
na_action = c("omit", "fail")
)
Arguments
data |
A data frame with one row per assessed unit (species or population). |
exposure, sensitivity, adaptive |
Character vectors naming the indicator columns of each component. Each component may use one column or many, and the sets may differ in size. 'adaptive' may be 'NULL' for an exposure-sensitivity (ES) assessment. |
outcomes |
Optional character vector naming observable vulnerability proxies. Needed by the latent, shape-constrained and penalised models, and by [ccva_validate()]. |
id |
Optional name of the column holding unit identifiers. If 'NULL', rows are labelled 'unit_1', 'unit_2', ... |
direction |
Optional named vector of '+1' / '-1' (or '"+"' / '"-"') giving, for each indicator, whether a higher value means *more* of its component (more exposure, more sensitivity, more adaptive capacity), and for each outcome whether a higher value means *more vulnerable*. Columns not listed default to '+1'. For example a thermal tolerance ratio, where higher means less sensitive, takes '-1'; range change, where a negative value is range loss, takes '-1'. |
coords |
Optional character vector of two column names (longitude, latitude) used by [ccva_plot()] for maps. |
formative |
Optional components whose indicators are complementary *facets* rather than interchangeable measures of one construct – e.g. adaptive capacity from dispersal ability and genetic diversity, which act through distinct mechanisms. Their indicators are not expected to covary, so [ccva_check()] does not flag a low Cronbach's alpha, and the latent model enters them as a composite (built by the component scoring method) instead of a reflective latent factor. Components not listed are reflective: their indicators are treated as interchangeable measures. |
na_action |
'"omit"' (default) drops rows with missing values in any used column, with a message; '"fail"' stops instead. |
Value
An object of class 'ccva_data'.
See Also
[ccva_simulate()] for data with a known latent structure.
Examples
d <- as_ccva(ccva_sim,
exposure = c("E1_risk", "E2_risk", "E3_risk"),
sensitivity = grep("^s[0-9]+_", names(ccva_sim), value = TRUE),
adaptive = grep("^a[0-9]+_", names(ccva_sim), value = TRUE),
outcomes = c("iucn", "pop_trend", "range_change"),
direction = c(pop_trend = -1, range_change = -1),
id = "species")
d
Run a complete CCVA
Description
Convenience wrapper: builds the 'ccva_data' (if given a data frame) and calls [ccva_combine()].
Usage
ccva(data, method = "latent", ...)
Arguments
data |
A 'ccva_data' object, or a data frame together with the component arguments of [as_ccva()]. |
method |
Combination method, see [ccva_combine()]. |
... |
Arguments for [as_ccva()] (when 'data' is a data frame) and [ccva_combine()]. |
Value
A 'ccva_fit' object.
Examples
fit <- ccva(ccva_sim_data(), method = "weighted",
component_method = "ordinal")
head(ccva_rank(fit))
Adjust trait measurements for assay methodology
Description
Physiological sensitivity traits such as heat tolerance (CTmax) are measured with different protocols – static or dynamic assays, different ramping rates, starting temperatures and acclimation regimes – and the protocol shifts the value obtained. Before species are compared, the methodological effect should be removed. This fits a linear model of the measurements on the method variables (with a unit effect when units are measured more than once) and returns every measurement adjusted to a common reference protocol, plus a per-unit summary ready to use as an indicator in [as_ccva()].
Usage
ccva_adjust_method(
data,
value,
method_vars,
unit = NULL,
reference = NULL,
weights = NULL
)
Arguments
data |
A data frame of measurements (one row per measurement). |
value |
Name of the measured trait column. |
method_vars |
Names of the method columns (numeric, e.g. ramp rate; or categorical, e.g. static / dynamic). |
unit |
Optional name of the unit column (species or population). Including it lets method effects be estimated within units. |
reference |
Optional named list of reference values for the method variables. Defaults: the median of numeric variables, the most common level of categorical ones. |
weights |
Optional name of a column of weights (e.g. sample size). |
Details
Method effects can only be separated from true differences between units when protocols vary within units, or are not confounded with them across units; aliased effects are reported.
Value
An object of class 'ccva_adjustment' with 'data' (including the adjusted column '<value>_adj'), 'by_unit' (mean adjusted value per unit), 'effects' (method coefficients), 'reference' and 'model'.
Examples
set.seed(1)
d <- data.frame(species = rep(paste0("sp", 1:20), each = 3),
ramp = rep(c(0.1, 0.25, 0.5), 20),
assay = rep(c("dynamic", "dynamic", "static"), 20))
d$ctmax <- 40 + rep(rnorm(20), each = 3) + 4 * d$ramp + rnorm(60, 0, 0.3)
adj <- ccva_adjust_method(d, "ctmax", c("ramp", "assay"), unit = "species")
adj
head(adj$by_unit)
Aggregate species vulnerability to sites or communities
Description
For spatial prioritisation: given which species occur where, summarise the vulnerability of each site's community – mean and maximum vulnerability, the number and share of highly vulnerable species, and the mean exposure, sensitivity and adaptive capacity of its species. With a [ccva_uncertainty()] result, the site means get intervals too.
Usage
ccva_aggregate(
fit,
occurrence,
site = "site",
unit = "species",
uncertainty = NULL,
coords = NULL,
level = 0.95
)
Arguments
fit |
A 'ccva_fit'. |
occurrence |
Either a data frame with one row per species presence at a site (columns named by 'site' and 'unit'), or a sites x species 0/1 matrix with dimnames. |
site, unit |
Column names in 'occurrence'. |
uncertainty |
Optional [ccva_uncertainty()] result. |
coords |
Optional data frame with columns 'site', 'x', 'y' for maps. |
level |
Interval coverage. |
Value
An object of class 'ccva_sites': a data frame per site, ordered from most to least vulnerable community.
Examples
fit <- ccva_combine(ccva_sim_data(), "weighted")
set.seed(1)
occ <- data.frame(site = rep(paste0("site", 1:8), each = 25),
species = sample(names(fit$score), 200, replace = TRUE))
occ <- unique(occ)
ccva_aggregate(fit, occ)
Calibrated risk predictions
Description
Rankings say which species are *more* vulnerable than others; managers need to know how *likely* a species is to decline. This calibrates a fit's vulnerability scores against an observed outcome (for example IUCN status of Vulnerable or worse, a declining population trend, or range loss) by logistic regression, and returns for every unit the probability of that outcome with a confidence interval.
Usage
ccva_calibrate(
fit,
outcome = NULL,
threshold = NULL,
event = NULL,
uncertainty = NULL,
R = 500,
level = 0.95,
seed = NULL
)
Arguments
fit |
A 'ccva_fit'. |
outcome |
Outcome column (default: the first outcome). Oriented so higher = more vulnerable. |
threshold |
Units with an oriented outcome at or above this value count as an event. Default: for an ordinal outcome (10 or fewer distinct values) the second-highest value, e.g. IUCN status Vulnerable or worse on a 0–3 scale; otherwise the median. |
event |
Optional logical vector of events, overriding 'outcome'. |
uncertainty |
Optional [ccva_uncertainty()] result. |
R |
Number of bootstrap replicates. |
level |
Interval coverage. |
seed |
Optional random seed. |
Details
Intervals come from a bootstrap over units that refits the calibration model. If a [ccva_uncertainty()] result is supplied, each replicate also uses a different draw of the vulnerability scores, so uncertainty in the scores themselves is propagated into the risk.
When the outcome was also used to fit the vulnerability model (latent, shape and penalised methods use the outcomes), this calibration is in-sample and optimistic. For an honest assessment, calibrate against an outcome the model did not see.
Value
An object of class 'ccva_calibration' with 'units' (probability and interval per unit), 'curve' (probability across the score range), 'bins' (observed vs predicted), 'metrics' (AUC, Brier score) and the 'model'.
Examples
fit <- ccva_combine(ccva_sim_data(), "weighted",
component_method = "ordinal")
cal <- ccva_calibrate(fit, outcome = "iucn", R = 200, seed = 1)
cal
Diagnose the indicators before combining them
Description
Summing indicators into a component assumes they measure one coherent construct; combining components assumes they are not redundant. Neither assumption is usually checked. This function checks both:
Usage
ccva_check(x, redundancy = 0.9, component_method = "mean")
Arguments
x |
A 'ccva_data' object. |
redundancy |
Absolute correlation above which a pair is flagged. |
component_method |
Method used to score components for the cross-component correlations. |
Details
* **internal consistency** of each component – Cronbach's alpha (raw and standardised), the mean inter-item correlation (which, unlike alpha, does not rise with the number of indicators) and corrected item-total correlations of its oriented indicators. Alpha is only expected to be high for *reflective* components, whose indicators are interchangeable measures; for components declared 'formative' in [as_ccva()] (distinct, complementary facets) a low alpha is expected and is not flagged; * **cross-component correlation** of the component scores (Spearman); * **redundancy** – indicator pairs, within or across components, with absolute Spearman correlation above 'redundancy'; * **dimensionality** – predictors per unit, flagging blocks where predictors approach or exceed the number of units (use a penalised method there).
Value
An object of class 'ccva_check'.
Examples
chk <- ccva_check(ccva_sim_data())
chk
Classify vulnerability scores into Low / Moderate / High
Description
Conventional CCVAs cut scores at 1/3 and 2/3, which silently assumes the scores are uniformly distributed and has no link to any observed outcome. This function offers that convention and three alternatives.
Usage
ccva_classify(
score,
cutoffs = "uniform",
data = NULL,
roc_outcome = NULL,
roc_levels = NULL,
labels = c("Low", "Moderate", "High")
)
Arguments
score |
Numeric vector of vulnerability scores. |
cutoffs |
One of * '"uniform"' – fixed cuts at 1/3 and 2/3 (Ofori et al. 2017); * '"quantile"' – sample tertiles (equal-sized classes); * '"mixture"' – natural clusters from a three-component Gaussian mixture fitted by EM; * ‘"roc"' – outcome-calibrated cuts maximising Youden’s J against an ordinal outcome (see 'roc_outcome', 'roc_levels'); * a numeric vector of two cut points. |
data |
A 'ccva_data' object; needed for '"roc"'. |
roc_outcome |
Outcome column used for '"roc"' (default: the first outcome). It is oriented so higher = more vulnerable. |
roc_levels |
Two outcome levels on the oriented scale: units at or above the first are "at least Moderate", at or above the second are "High". Defaults to the second and third distinct values. |
labels |
Class labels. |
Value
An ordered factor with attribute 'cutoffs'.
Examples
fit <- ccva_combine(ccva_sim_data(), "weighted")
table(ccva_classify(fit$score, "uniform"))
table(ccva_classify(fit$score, "roc", data = fit$data))
Combine the components into vulnerability
Description
Scores the three components and combines them into a vulnerability score for every unit, under a chosen model. Constraints from [ccva_constraints()] are imposed on predictors and on each component's role in every model that can express them.
Usage
ccva_combine(
x,
method = c("weighted", "shape", "latent", "penalised"),
component_method = "mean",
component_args = list(),
weights = NULL,
constraints = NULL,
response = NULL,
shared_error = NULL,
max_indicators = 30,
k = NULL,
alpha = 1,
cutoffs = "uniform",
...
)
Arguments
x |
A 'ccva_data' object. |
method |
Combination method; see Methods. |
component_method |
Scoring method for the components: one string for all, or a named list / vector per component (see [ccva_component()]). |
component_args |
Optional named list (per component) of extra arguments for [ccva_component()], e.g. 'weights' or 'breaks'. |
weights |
Component weights for '"weighted"', named 'exposure', 'sensitivity', 'adaptive'. Default equal. |
constraints |
A [ccva_constraints()] object. Defaults to [ccva_default_constraints()]; use [ccva_unconstrained()] for free estimation. |
response |
For '"shape"': an outcome column, a numeric vector (higher = more vulnerable), or 'NULL' to use the first principal component of all outcomes. |
shared_error |
For '"latent"': a list of character vectors, each a group of indicators with a common error source. |
max_indicators |
For '"latent"': a component with more indicators than this (or with only one) enters as its observed component score instead of a latent factor. Default 30. |
k |
Basis dimension for '"shape"' splines; chosen from 'n' if 'NULL'. |
alpha |
Elastic-net mixing for '"penalised"' (1 = LASSO). |
cutoffs |
Classification of scores into Low / Moderate / High; see [ccva_classify()]. |
... |
Passed to registered combine methods. |
Value
An object of class 'ccva_fit': 'score' (vulnerability in \[0, 1\], higher = more vulnerable), 'class', 'components' (fitted [ccva_component()] objects), 'component_scores', 'model', 'details', 'notes' (any constraint a method could not express) and 'predict'.
Methods
- '"weighted"'
The conventional index (Ofori et al. 2017) with the corrected normalisation
V = (w_E E + w_S S - w_A A + w_A) / (w_E + w_S + w_A), which equals(E + S - A + 1)/3for equal weights and maps the full range onto \[0, 1\] without clipping. Without adaptive-capacity indicators it is(E + S)/2. With [constrain_moderator()] adaptive capacity has no main effect:V \propto w_E E (1 - \gamma_E A) + w_S S (1 - \gamma_S A). Use ‘component_method = "ordinal"' to reproduce Ofori’s 1–3 scoring.- '"shape"'
Shape-constrained additive model (Pya and Wood 2015, package scam) of an observed 'response' on the component scores. Component signs become monotone increasing / decreasing splines, so the *shape* is learned from data while the *direction* is fixed by ecology. With [constrain_moderator()] it fits the interaction surfaces
f_{EA}(E, A) + f_{SA}(S, A), monotone in each argument (adaptive capacity as moderator only).- '"latent"'
Structural equation model (lavaan) in which vulnerability
V^*is a latent variable measured by the outcome proxies and caused by latent exposure, sensitivity and adaptive capacity, each measured by its own indicators (a full MIMIC model). Every constraint type is imposed as a linear (in)equality on loadings and paths. Indicators sharing an error source (e.g. SDM metrics with a common denominator) are declared in 'shared_error' and modelled with an orthogonal method factor.- '"penalised"'
Two-stage model for high-dimensional predictors: (1) latent vulnerability is estimated from the outcome proxies alone; (2) it is regressed on *all* indicators with a LASSO / elastic net (glmnet) whose coefficient signs follow the component and indicator constraints. Selects which predictors drive vulnerability.
Methods added with [ccva_register()] are also accepted.
References
Ofori, B. Y. et al. (2017) *Scientific Reports* 7, 12979. Pya, N. and Wood, S. N. (2015) *Statistics and Computing* 25, 543–559. Rosseel, Y. (2012) *Journal of Statistical Software* 48(2).
See Also
[ccva()], [ccva_compare()], [ccva_uncertainty()], [ccva_plot()]
Examples
d <- ccva_sim_data()
# Conventional Ofori-style weighted index
w <- ccva_combine(d, "weighted", component_method = "ordinal")
w
# Constrained latent model (the default constraints)
l <- ccva_combine(d, "latent",
shared_error = list(c("E1_risk", "E2_risk", "E3_risk")))
l
cor(l$score, d$truth$V_star, method = "spearman")
Compare several CCVA fits
Description
Compare several CCVA fits
Usage
ccva_compare(..., truth = NULL)
Arguments
... |
Named 'ccva_fit' objects (or a single named list of them), all fitted to the same units. |
truth |
Optional true vulnerability; defaults to the simulated truth when present. |
Value
An object of class 'ccva_comparison' with a 'table' (validation correlations per method, class agreement with the first fit), ‘rank_cor' (Spearman correlations between methods’ scores) and the fits.
Examples
d <- ccva_sim_data()
cmp <- ccva_compare(
ofori = ccva_combine(d, "weighted", component_method = "ordinal"),
latent = ccva_combine(d, "latent",
shared_error = list(c("E1_risk", "E2_risk", "E3_risk"))))
cmp
Score the exposure, sensitivity and adaptive-capacity components
Description
Each component is computed from its own indicators (its predictors) by a chosen method. Indicators are first oriented with the 'direction' given in [as_ccva()], so that a higher value always means more of the component.
Usage
ccva_component(
x,
component = c("exposure", "sensitivity", "adaptive"),
method = "mean",
weights = NULL,
breaks = NULL,
anchor = NULL,
alpha = 1,
constraints = NULL,
...
)
ccva_exposure(x, method = "mean", ...)
ccva_sensitivity(x, method = "mean", ...)
ccva_adaptive(x, method = "mean", ...)
Arguments
x |
A 'ccva_data' object. |
component |
One of '"exposure"', '"sensitivity"', '"adaptive"'. |
method |
Scoring method; see Details. |
weights |
Optional named numeric vector of indicator weights (for ‘"ordinal"': maximum scores, e.g. Ofori’s 11, 10, 9, ... for sensitivity). Missing indicators get weight 1. |
breaks |
For '"ordinal"', an optional named list giving, per indicator, two cut points on the raw scale. Values above the upper cut score 3 (more of the component) when the direction is '+1', and 1 when it is '-1'. |
anchor |
For '"penalised"': an outcome column name, a numeric vector (higher = more vulnerable), or 'NULL' to use the first principal component of all outcomes. |
alpha |
Elastic-net mixing for '"penalised"': 1 = LASSO, 0 = ridge. |
constraints |
A [ccva_constraints()] object. Predictor-level rules are honoured: fixed-at-zero indicators are dropped; signs and bounds restrict the penalised coefficients. |
... |
Passed to registered methods. |
Details
Methods:
- '"ordinal"'
The Ofori et al. (2017) scheme: each indicator is scored 1–3 (by 'breaks', or by sample tertiles when 'breaks' is 'NULL'), and the scores are summed with optional 'weights' (the maximum score of each indicator) and divided by the maximum. Scores therefore lie in \[1/3, 1\], exactly as in the original study. Use it to reproduce conventional assessments and to measure what discretisation loses.
- '"mean"'
Continuous: each indicator rescaled to \[0, 1\], then a weighted mean. No information is discarded.
- '"pca"'
First principal component of the standardised indicators, signed so loadings are positive on average, rescaled to \[0, 1\]. Data-driven weights.
- '"penalised"'
Penalised regression (LASSO by default; set 'alpha') of an 'anchor' on the indicators, with coefficient signs constrained to the ecological direction. Designed for high-dimensional blocks where predictors outnumber units, such as genomic markers. Needs the glmnet package.
Methods added with [ccva_register()] are also accepted.
Value
An object of class 'ccva_component' with elements 'score' (named numeric vector), 'importance' (per-indicator weight, loading or coefficient), 'method', 'component' and 'predict' (a function scoring new data on the same scale).
See Also
[ccva_combine()], which calls these for you.
Examples
d <- ccva_sim_data()
e_ord <- ccva_exposure(d, method = "ordinal")
e_cont <- ccva_exposure(d, method = "mean")
cor(e_ord$score, e_cont$score, method = "spearman")
s <- ccva_sensitivity(d, method = "pca")
head(sort(s$importance, decreasing = TRUE))
Constraints on predictors and components
Description
Ecological knowledge enters a CCVA as explicit constraints, at two levels:
Usage
ccva_constraints(..., defaults = TRUE)
ccva_default_constraints()
ccva_unconstrained()
constrain_sign(target, sign = c("+", "-", "direction"))
constrain_bounds(target, lower = -Inf, upper = Inf)
constrain_equal(targets)
constrain_fixed(target, value)
constrain_link(from, to, link_sign = c("free", "+", "-"))
constrain_shape(target, shape = c("concave", "convex"))
constrain_moderator(gamma = c(0.5, 0.4))
Arguments
... |
'ccva_rule' objects from the 'constrain_*()' helpers. |
defaults |
Logical. If 'TRUE' (default), start from [ccva_default_constraints()] (component signs plus indicator signs taken from the data's 'direction') and add '...' on top; later rules for the same target override earlier ones. |
target |
For component-level rules, one of '"exposure"', '"sensitivity"', '"adaptive"'. For predictor-level rules, an indicator or outcome column name. '".indicators"' applies to every indicator and outcome. |
sign |
'"+"', '"-"', or for '".indicators"' the special value ‘"direction"' (use each column’s direction from [as_ccva()]). |
lower, upper |
Bounds on the effect (component level) or loading / weight (predictor level). Use '-Inf' / 'Inf' for one-sided bounds. |
targets |
Character vector of two or more indicators (within the same component) whose loadings / weights are constrained equal. |
value |
Fixed value. '0' removes the indicator or component effect. |
from, to |
Components for a directed structural link: 'from' affects 'to' (e.g. adaptive capacity through dispersal shapes the SDM-derived exposure a species will face). |
link_sign |
Sign of the link: '"free"', '"+"' or '"-"'. |
shape |
For the shape-constrained model: '"concave"' (e.g. an exposure effect that rises steeply then plateaus) or '"convex"' (accelerating, e.g. highly sensitive species disproportionately affected). Combined with the component's sign this gives monotone concave / convex splines. Unimodal shapes are not available. |
gamma |
Moderation strengths 'c(exposure, sensitivity)' used by the weighted method: adaptive capacity reduces the exposure and sensitivity effects by up to these proportions. |
Details
* **Predictor level** – the role of an indicator (or outcome proxy) within its component: the sign of its loading or weight, bounds, equality with other indicators, or a fixed value (0 drops it). * **Component level** – how a component enters vulnerability: exposure and sensitivity raise it, adaptive capacity lowers it; bounds on the effects; or adaptive capacity acting only as a *moderator* of exposure and sensitivity, with no main effect. * **Between components** – the three components are not independent. [constrain_link()] declares a directed dependency, e.g. dispersal-driven adaptive capacity shaping SDM-derived exposure. In the latent SEM it is a structural path, and the indirect and total effects of the source component on vulnerability are reported; in the other models it is resolved in two stages, by removing from the target component the part explained by the source, so it is not counted twice.
Constraints are built from the 'constrain_*()' helpers and collected with 'ccva_constraints()'. The same object is honoured by every combination method of [ccva_combine()] that can express it: sign, bound, equality and fixed constraints become inequality / equality restrictions on loadings and paths in the latent SEM; signs become monotone-increasing or -decreasing splines in the shape-constrained model and coefficient limits in the penalised model; the moderator role becomes an interaction surface in the shape and weighted models. A constraint a method cannot express is reported, never silently ignored.
Sign constraints on loadings also solve the sign-indeterminacy of latent factors: with every loading pinned to its ecological direction, the latent scores cannot come out reversed.
Value
An object of class 'ccva_constraints'.
See Also
[ccva_combine()], [ccva_register()]
Examples
# Default ecological constraints
ccva_constraints()
# Adaptive capacity as moderator only, thermal tolerance loading fixed
# equal to range size, and generation length dropped
ccva_constraints(
constrain_moderator(),
constrain_equal(c("s1_thermal", "s2_range")),
constrain_fixed("s10_genlen", 0)
)
# No constraints at all (for comparison)
ccva_unconstrained()
List available methods
Description
List available methods
Usage
ccva_methods()
Value
A data frame of built-in and registered methods.
Examples
ccva_methods()
Plot any step of a CCVA
Description
One entry point for the figures of every stage. 'ccva_plot()' dispatches on the class of 'object'; 'type' picks the figure. Every plot is a 'ggplot' object, so it can be themed, combined or saved with 'ggplot2::ggsave()'.
Usage
ccva_plot(object, type = NULL, n = 15, ...)
Arguments
object |
A 'ccva_data', 'ccva_check', 'ccva_component', 'ccva_fit', 'ccva_comparison' or 'ccva_uncertainty' object. |
type |
Figure type (see table). 'NULL' gives the first listed. |
n |
For rankings and interval plots, the number of units shown at each end ('"ranking"') or in total ('"intervals"', '"pairwise"'). |
... |
Unused. |
Details
| object | 'type' | shows | |—|—|—| | 'ccva_data' | '"indicators"' | distribution of every indicator, grouped by component | | | '"correlation"' | indicator correlation matrix, ordered by component | | ‘ccva_check' | '"alpha"' | Cronbach’s alpha per component against thresholds | | | '"correlation"' | cross-component correlations | | 'ccva_component' | '"importance"' | weight / loading / coefficient of each indicator | | | '"distribution"' | distribution of the component score | | 'ccva_fit' | '"structure"' | path diagram: components to vulnerability, with effects | | | '"components"' | the three component scores side by side | | | '"scores"' | vulnerability distribution with class cut-offs | | | '"ranking"' | most and least vulnerable units with their components | | | ‘"contributions"' | how each component pushes each unit’s score (weighted) | | | '"effects"' | shape curves, latent loadings or penalised coefficients | | | '"map"' | vulnerability over coordinates | | 'ccva_comparison' | '"truth"' | each method against the true vulnerability | | | '"ranks"' | rank of each unit under two methods | | | '"validation"' | correlation of each method with each target | | 'ccva_uncertainty' | '"intervals"' | score intervals, ranked | | | '"pairwise"' | probability one unit is more vulnerable than another |
Value
A 'ggplot' object.
Examples
d <- ccva_sim_data()
ccva_plot(d, "indicators")
fit <- ccva_combine(d, "weighted", component_method = "ordinal")
ccva_plot(fit, "structure")
ccva_plot(fit, "ranking", n = 8)
Rank units by vulnerability
Description
Rank units by vulnerability
Usage
ccva_rank(fit, uncertainty = NULL)
Arguments
fit |
A 'ccva_fit'. |
uncertainty |
Optional [ccva_uncertainty()] result to add intervals. |
Value
Data frame ordered from most to least vulnerable.
Examples
fit <- ccva_combine(ccva_sim_data(), "weighted")
head(ccva_rank(fit))
Match methods to the data available
Description
Turns general guidance – shape-constrained parametric models for small samples, regularised regression for regional compilations, flexible non-parametric methods for global databases, with internal consistency checks, structural or two-stage handling of dependencies among components, and honest uncertainty in every case – into concrete advice for a given dataset, based on the number of units and the number of predictors per component.
Usage
ccva_recommend(x)
Arguments
x |
A 'ccva_data' object. |
Details
The sample-size thresholds (50 and 150 units) reflect rough feasibility: correlated additive latent models need about 50 units, interaction surfaces about 150. They are guides, not rules.
Value
An object of class 'ccva_recommendation' with the 'tier', a 'profile' of the data and a table of 'steps'.
Examples
ccva_recommend(ccva_sim_data())
ccva_recommend(ccva_simulate(40, seed = 1))
Register a new component or combination method
Description
The framework grows by contribution. A registered method is used exactly like a built-in one, through the 'method' argument of the component scorers or of [ccva_combine()].
Usage
ccva_register(name, fun, type = c("component", "combine"), description = "")
ccva_unregister(name, type = c("component", "combine"))
Arguments
name |
Method name. |
fun |
The method function. |
type |
'"component"' or '"combine"'. |
description |
One-line description shown by [ccva_methods()]. |
Details
A **component** method is a function 'function(X, anchor, signs, ...)' where 'X' is the oriented indicator matrix (higher = more of the component), 'anchor' an optional numeric vector (oriented vulnerability proxy) and 'signs' the resolved indicator sign constraints. It must return a list with 'score' (numeric, one per row) and 'predict', a function of a new 'X' returning scores on the same scale.
A **combine** method is a function 'function(x, components, constraints, ...)' receiving the 'ccva_data', the fitted component scores (data frame) and the resolved constraints. It must return a list with 'score' (vulnerability, higher = more vulnerable) and optionally 'model', 'details' and 'predict' (a function of new 'ccva_data').
Value
Invisibly, the updated registry listing.
Examples
# A median-based component score
ccva_register("median", function(X, anchor, signs, ...) {
z <- scale(X)
list(score = apply(z, 1, stats::median),
predict = function(newX) apply(scale(newX,
attr(z, "scaled:center"), attr(z, "scaled:scale")), 1,
stats::median))
}, type = "component", description = "Median of standardised indicators")
ccva_methods()
ccva_unregister("median", "component")
Write a reproducible CCVA report
Description
Renders an HTML report of a fit: the data and diagnostics, every component, the combination model and its constraints, the ranking, and optionally uncertainty and a method comparison. Needs rmarkdown (and pandoc).
Usage
ccva_report(
fit,
file = file.path(tempdir(), "ccva_report.html"),
uncertainty = NULL,
comparison = NULL,
title = "Climate change vulnerability assessment",
open = interactive()
)
Arguments
fit |
A 'ccva_fit'. |
file |
Output HTML file. Defaults to a file in the session's temporary directory; give a path to keep the report. |
uncertainty |
Optional [ccva_uncertainty()] result. |
comparison |
Optional [ccva_compare()] result. |
title |
Report title. |
open |
Open the report in a browser when done. |
Value
The path to the report, invisibly.
Examples
if (requireNamespace("rmarkdown", quietly = TRUE) &&
rmarkdown::pandoc_available()) {
fit <- ccva_combine(ccva_sim_data(), "weighted")
path <- ccva_report(fit, open = FALSE)
file.exists(path)
}
Compute exposure predictors from species distribution model output
Description
Turns the cell counts of thresholded current and future SDM habitat maps into the three exposure indices of Ofori et al. (2017), and recodes them so that a higher value always means more exposure (risk direction), ready to be used as exposure indicators in [as_ccva()].
Usage
ccva_sdm_exposure(n_current, n_future, n_overlap, n_protected = NULL)
Arguments
n_current |
Number of suitable cells under current climate. |
n_future |
Number of suitable cells under future climate. |
n_overlap |
Number of cells suitable under both. |
n_protected |
Optional number of currently suitable cells inside protected areas. |
Details
E_1 = (N_{future} - N_{current}) / N_{current}
E_2 = N_{overlap} / N_{current}
E_3 = N_{protected} / N_{current}
with risk recoding E_{1,risk} = -E_1, E_{2,risk} = 1 - E_2,
E_{3,risk} = 1 - E_3. The three share the denominator
N_{current}, so their residuals are correlated; declare them in
'shared_error' of [ccva_combine()] when using the latent model.
The SDM itself (MaxEnt, BIOCLIM, an ensemble, ...) is fitted with the user's preferred package; this function only needs the cell counts.
Value
A data frame with the raw indices ('E1_change', 'E2_overlap', 'E3_protected') and their risk-coded versions ('E1_risk', 'E2_risk', 'E3_risk').
Examples
ccva_sdm_exposure(n_current = c(120, 80), n_future = c(60, 95),
n_overlap = c(50, 70), n_protected = c(30, 10))
Simulated CCVA dataset
Description
300 simulated species generated by [ccva_simulate()] with 'seed = 99' and the linear structural model. Contains the observed columns a modeller would see plus the latent truth for validation. All values are simulated and have no biological meaning.
Usage
ccva_sim
Format
A data frame with 300 rows and 26 columns:
- species
Unit identifier.
- E1_risk
Exposure: habitat loss risk (SDM-derived, higher = more exposed).
- E2_risk
Exposure: lack of overlap between current and future habitat.
- E3_risk
Exposure: lack of protection of current habitat. The three exposure risks share a denominator, hence correlated residuals.
- s1_thermal
Sensitivity: thermal tolerance (higher = more sensitive).
- s2_range
Sensitivity: small geographic range.
- s3_climzones
Sensitivity: few climate zones occupied.
- s4_habitat
Sensitivity: habitat specialisation.
- s5_diet
Sensitivity: diet specialisation.
- s6_reprorate
Sensitivity: low reproductive rate.
- s7_repromode
Sensitivity: reproductive mode.
- s8_clutch
Sensitivity: small clutch size.
- s9_survival
Sensitivity: low offspring survival.
- s10_genlen
Sensitivity: long generation length.
- s11_lifespan
Sensitivity: lifespan.
- a1_genetic
Adaptive capacity: genetic diversity (higher = more capacity).
- a2_bodysize
Adaptive capacity: body size as a dispersal proxy.
- a3_lowfrag
Adaptive capacity: low habitat fragmentation.
- a4_microhab
Adaptive capacity: microhabitat buffering.
- iucn
IUCN-like status, 0 (least concern) to 3 (endangered).
- pop_trend
Population trend: -1 declining, 0 stable, 1 increasing.
- range_change
Proportional range change; negative = loss.
- E_star
Latent exposure (simulation truth).
- S_star
Latent sensitivity (simulation truth).
- A_star
Latent adaptive capacity (simulation truth).
- V_star
Latent vulnerability (simulation truth).
Source
Simulated with [ccva_simulate()]; see 'data-raw/ccva_sim.R'.
Examples
head(ccva_sim[, 1:6])
Specification of the bundled simulated data
Description
Convenience wrapper that turns [ccva_sim] into a 'ccva_data' object with the correct component tags and directions, and attaches the latent truth.
Usage
ccva_sim_data(data = ccva::ccva_sim)
Arguments
data |
Defaults to [ccva_sim]. |
Value
A 'ccva_data' object with a 'truth' element.
Examples
d <- ccva_sim_data()
d
Simulate CCVA data with a known latent structure
Description
Generates data from a three-layer data-generating process, so that every method can be checked against the truth:
Usage
ccva_simulate(
n = 300,
nonlinear = FALSE,
phi = matrix(c(1, 0.3, -0.2, 0.3, 1, -0.25, -0.2, -0.25, 1), 3, 3),
b = c(E = 0.5, S = 0.35, A = 0.25),
sd_zeta = 0.3,
n_genomic = 0,
n_causal = 10,
link_AE = 0,
seed = NULL
)
Arguments
n |
Number of units (species). The full latent model has 21 indicators and four latent factors; use a few hundred for stable fits. |
nonlinear |
Logical; use the nonlinear structural model for
|
phi |
3 x 3 correlation matrix of |
b |
Structural coefficients 'c(E, S, A)'; adaptive capacity enters with a negative sign. |
sd_zeta |
Standard deviation of the structural disturbance. |
n_genomic |
Number of genomic markers (coded 0/1/2) to add to the
adaptive-capacity block, for testing penalised methods when predictors
outnumber units. The first 'n_causal' markers carry signal from
|
n_causal |
Number of informative genomic markers. |
link_AE |
Strength of a directed dependency of exposure on adaptive
capacity, |
seed |
Optional random seed. |
Details
* **Layer 1** – correlated latent exposure E^*, sensitivity
S^* and adaptive capacity A^*.
* **Layer 2** – latent vulnerability
V^* = b_E E^* + b_S S^* - b_A A^* + \zeta (linear), or a nonlinear
version with an exposure plateau, convex sensitivity and adaptive
capacity acting only as a moderator.
* **Layer 3** – observed indicators: three SDM-derived exposure risks
with a shared-denominator nuisance, eleven sensitivity traits, four
adaptive-capacity traits, optional genomic markers, and three
vulnerability proxies (IUCN-like status, population trend, range change).
All indicators are continuous except the proxies 'iucn' (0–3) and 'pop_trend' (-1, 0, 1), which are ordinal by nature. Ofori-style 1–3 scores are produced later by 'method = "ordinal"' in the component scorers, so the information lost by discretising can be measured.
Value
A 'ccva_data' object (see [as_ccva()]) with an extra element 'truth', a data frame of the latent values 'E_star', 'S_star', 'A_star', 'V_star'. Use 'x$data' for the raw data frame.
See Also
[ccva_sim] for a bundled simulated dataset.
Examples
sim <- ccva_simulate(n = 200, seed = 1)
sim
head(sim$truth)
# High-dimensional adaptive-capacity block (p > n)
sim_g <- ccva_simulate(n = 150, n_genomic = 400, seed = 1)
length(sim_g$indicators$adaptive)
Compute thermal sensitivity predictors
Description
Mechanistic sensitivity predictors from measured thermal limits:
warming tolerance WT = CT_{max} - T_{hab} and thermal safety margin
TSM = T_{opt} - T_{hab}. Smaller (or negative) values mean the
organism is closer to its limit, i.e. more sensitive, so give these
columns direction '-1' in [as_ccva()].
Usage
ccva_thermal_margin(ctmax, t_habitat, topt = NULL)
Arguments
ctmax |
Critical thermal maximum. |
t_habitat |
Habitat (or operative body) temperature experienced by the unit, e.g. extracted from a climate layer at its coordinates. |
topt |
Optional thermal optimum. |
Value
A data frame with 'warming_tolerance' and, if 'topt' is given, 'safety_margin'.
Examples
ccva_thermal_margin(ctmax = c(42, 45), t_habitat = c(31, 28),
topt = c(35, 36))
Quantify uncertainty in vulnerability scores and rankings
Description
Published CCVAs usually report a sorted list of point estimates, which implies a precision the data rarely support. Two complementary sources of uncertainty are available:
Usage
ccva_uncertainty(
fit,
type = c("bootstrap", "weights"),
R = 200,
level = 0.95,
robust = 0.05,
score_error = TRUE,
seed = NULL,
progress = interactive()
)
Arguments
fit |
A 'ccva_fit'. |
type |
'"bootstrap"' or '"weights"'. |
R |
Number of replicates. |
level |
Interval coverage. |
robust |
Threshold for calling a pairwise ranking robust. |
score_error |
For the latent model, add each unit's factor-score prediction error to the bootstrap draws (recommended). |
seed |
Optional random seed. |
progress |
Show a progress bar. |
Details
* 'type = "bootstrap"' – **sampling uncertainty**: units are resampled with replacement, the *whole* pipeline (component scoring, constraints, combination model) is refitted on each resample, and the original units are scored with the refitted model. For the latent model each unit's score is a prediction of an unobserved quantity, so (with 'score_error = TRUE') its factor-score standard error is added to every replicate; without it, intervals reflect parameter uncertainty only and are far too narrow. * 'type = "weights"' – **weighting uncertainty** for the weighted index (a partial-identification view): component weights are drawn uniformly from the simplex, so the intervals show how much a ranking depends on the arbitrary choice of weights.
For each unit the result gives an interval for its score and for its rank; for each pair of units, the probability that one is more vulnerable than the other. A ranking of two units is called *robust* when that probability is above '1 - robust' or below 'robust'.
Value
An object of class 'ccva_uncertainty' with 'summary' (one row per unit: estimate, interval, rank interval), 'pairwise' (matrix of P(row unit more vulnerable than column unit)), 'robust_share', 'overlap_share' and the raw 'draws'.
Examples
fit <- ccva_combine(ccva_sim_data(), "weighted")
u <- ccva_uncertainty(fit, "weights", R = 500, seed = 1)
u
ub <- ccva_uncertainty(fit, "bootstrap", R = 50, seed = 1)
head(ub$summary)
Validate vulnerability scores against observed outcomes
Description
A CCVA score that has never been compared with any observable outcome is unvalidated. This reports the rank correlation of a fit's scores with every outcome proxy (oriented so a positive correlation is good) and, for simulated data, with the latent truth.
Usage
ccva_validate(fit, truth = NULL)
Arguments
fit |
A 'ccva_fit'. |
truth |
Optional numeric vector of true vulnerability. If 'NULL', 'fit$data$truth$V_star' is used when present. |
Details
Note: when the outcomes were also used to fit the model (latent, shape and penalised methods), correlation with them measures fit, not out-of-sample validity; use held-out outcomes or the truth for that.
Value
A data frame with one row per target: Spearman and Kendall correlations.
Examples
fit <- ccva_combine(ccva_sim_data(), "weighted")
ccva_validate(fit)
Predict vulnerability for new units
Description
Predict vulnerability for new units
Usage
## S3 method for class 'ccva_fit'
predict(object, newdata, ...)
Arguments
object |
A 'ccva_fit'. |
newdata |
A 'ccva_data' object (or data frame with the same columns) for the new units. |
... |
Unused. |
Value
Numeric vector of vulnerability on the scale of the training fit (values outside \[0, 1\] indicate units beyond the training range).
Colours and theme used by ccva plots
Description
'ccva_colours' maps each component (and vulnerability) to a fixed colour, so a component looks the same in every figure. The palette was checked for colour-vision-deficiency separation; facet and direct labels carry identity too, so colour is never the only cue.
Usage
theme_ccva(base_size = 11)
ccva_colours
Arguments
base_size |
Base font size. |
Format
'ccva_colours': a named character vector.
Value
'theme_ccva()' returns a ggplot2 theme.
Examples
ccva_colours