| Title: | An R implementation of the InSiGHTS framework |
|---|---|
| Description: | Implements the InSiGHTS (Index of Habitat Availability) modelling framework for assessing how climate change and land-use change affect the availability of suitable habitat for species over time. The package refines binary range maps or probabilistic species distribution models (SDMs) with fractional land-use layers to produce area-of-habitat (AOH) estimates across present and future time steps. An optional temporal discount function accounts for habitat maturity, allowing newly established land cover to be weighted according to its effective ecological value. Output summaries express habitat availability as absolute area or as a relative index with respect to a user-defined reference year. The package is designed to work seamlessly with the ibis.iSDM package but can also accept any SpatRaster or stars object as range input. |
| Authors: | Martin Jung [aut, cre] (ORCID: <https://orcid.org/0000-0002-7569-1390>) |
| Maintainer: | Martin Jung <[email protected]> |
| License: | CC BY 4.0 |
| Version: | 0.8 |
| Built: | 2026-06-05 23:27:58 UTC |
| Source: | https://github.com/iiasa/insights |
The purpose of this function is to create the range from several derivative
variables. The information to do so is taken from the variable name and it
is assumed that those have been created by ibis.iSDM::predictor_derivate() function.
This function return the range of values from the original data that fall within the set of coefficients. Currently only positive coefficients are taken by default.
create_derivate_range(env, varname, co, to_binary = FALSE)create_derivate_range(env, varname, co, to_binary = FALSE)
env |
The original variable stacks as |
varname |
A |
co |
A set of coefficients obtained via |
to_binary |
A |
This function really only makes sense for 'bin', 'thresh' and
'hinge' transformations.
For 'hinge' the combined min is returned.
A SpatRaster object containing the predictor range.
This is rather an internal function created for a specific use and project. It might be properly described in an example later.
Martin Jung
## Not run: # Assuming derivates of temperature have been created for a model, this # recreates the range over which they apply. deriv <- create_derivate_range(env, varname = "Temperature", co = coef(fit), to_binary = TRUE) ## End(Not run)## Not run: # Assuming derivates of temperature have been created for a model, this # recreates the range over which they apply. deriv <- create_derivate_range(env, varname = "Temperature", co = coef(fit), to_binary = TRUE) ## End(Not run)
Apply an area-of-habitat (AOH) refinement to a binary or fractional range
estimate using land-use or habitat layers already expressed as area per cell.
Use this method when lu values are continuous areal units such as
km2. For cell shares or suitability weights in [0, 1], use
insights_fraction() instead.
If lu has multiple layers or attributes, they are summed before being
applied to the range. Optional other layers can be supplied as
additional suitability or condition masks, but they must already be scaled to
[0, 1]; raw environmental layers such as elevation should be converted
to a suitability mask before calling this function.
Raster inputs are reprojected, cropped, and resampled to the range geometry
when needed. Temporal stars inputs may use a time or Time
dimension name. If outfile is supplied, the extension is adjusted to
.tif for raster output or .nc for stars output.
insights_area(range, lu, other, outfile = NULL) ## S4 method for signature 'SpatRaster,SpatRaster,ANY,character' insights_area(range,lu,other,outfile) ## S4 method for signature 'SpatRaster,stars,ANY,character' insights_area(range,lu,other,outfile) ## S4 method for signature 'stars,stars,ANY,character' insights_area(range,lu,other,outfile) ## S4 method for signature 'stars,SpatRaster,ANY,character' insights_area(range,lu,other,outfile) ## S4 method for signature 'ANY,ANY,ANY,character' insights_area(range,lu,other,outfile)insights_area(range, lu, other, outfile = NULL) ## S4 method for signature 'SpatRaster,SpatRaster,ANY,character' insights_area(range,lu,other,outfile) ## S4 method for signature 'SpatRaster,stars,ANY,character' insights_area(range,lu,other,outfile) ## S4 method for signature 'stars,stars,ANY,character' insights_area(range,lu,other,outfile) ## S4 method for signature 'stars,SpatRaster,ANY,character' insights_area(range,lu,other,outfile) ## S4 method for signature 'ANY,ANY,ANY,character' insights_area(range,lu,other,outfile)
range |
A |
lu |
A |
other |
Optional |
outfile |
A writeable |
Either a SpatRaster or temporal stars object or nothing if outputs are written directly to drive.
This function does not infer species-habitat relationships from raw land-use
classes. Select, weight, or transform land-use and condition layers before
calling insights_area().
No checks are conducted on whether supplied area layers add up to the area
of a grid cell.
Martin Jung
Rondinini, Carlo, and Piero Visconti. "Scenarios of large mammal loss in Europe for the 21st century." Conservation Biology 29, no. 4 (2015): 1028-1036.
Visconti, Piero, Michel Bakkenes, Daniele Baisero, Thomas Brooks, Stuart HM Butchart, Lucas Joppa, Rob Alkemade et al. "Projecting global biodiversity indicators under future development scenarios." Conservation Letters 9, no. 1 (2016): 5-13.
require(terra) range <- terra::rast(system.file( "extdata/example_range.tif", package = "insights", mustWork = TRUE )) lu_fraction <- terra::rast(system.file( "extdata/Grassland.tif", package = "insights", mustWork = TRUE )) / 10000 # Convert a fractional land-use layer to area per cell in km2. lu_km2 <- lu_fraction * terra::cellSize(lu_fraction, unit = "km") out <- insights_area(range = range, lu = lu_km2) # The output is already in area units, so do not multiply by cell area again. insights_summary(out, toArea = FALSE)require(terra) range <- terra::rast(system.file( "extdata/example_range.tif", package = "insights", mustWork = TRUE )) lu_fraction <- terra::rast(system.file( "extdata/Grassland.tif", package = "insights", mustWork = TRUE )) / 10000 # Convert a fractional land-use layer to area per cell in km2. lu_km2 <- lu_fraction * terra::cellSize(lu_fraction, unit = "km") out <- insights_area(range = range, lu = lu_km2) # The output is already in area units, so do not multiply by cell area again. insights_summary(out, toArea = FALSE)
This function applies a temporal discount to land-use layers based on a corresponding age or maturity variable. The age variable is always connected to a specific land-use class (e.g. forest age linked to forest fraction) and represents increasing value over time.
Newly established habitat (low age) does not provide full habitat value.
The target_age parameter controls how quickly the age translates to
effective habitat value: it is the age at which habitat reaches
target of its full value. The function produces a discounted version
of lu by applying a maturity factor derived from the age:
where is the land-use value, is the cell age,
is target_age, and is target. Internally,
this is equivalent to deriving the per-age discount rate:
and applying:
At age = 0: the factor is 0 – no habitat value for
brand-new land-use.
At age = target_age: the factor is target, e.g.
0.95 by default.
As age increases: the factor approaches 1 – mature
habitat reaches full value.
insights_discount(lu, age, target_age = 20, target = 0.95) ## S4 method for signature 'SpatRaster,SpatRaster' insights_discount(lu,age,target_age,target) ## S4 method for signature 'SpatRaster,stars' insights_discount(lu,age,target_age,target) ## S4 method for signature 'stars,SpatRaster' insights_discount(lu,age,target_age,target) ## S4 method for signature 'stars,stars' insights_discount(lu,age,target_age,target)insights_discount(lu, age, target_age = 20, target = 0.95) ## S4 method for signature 'SpatRaster,SpatRaster' insights_discount(lu,age,target_age,target) ## S4 method for signature 'SpatRaster,stars' insights_discount(lu,age,target_age,target) ## S4 method for signature 'stars,SpatRaster' insights_discount(lu,age,target_age,target) ## S4 method for signature 'stars,stars' insights_discount(lu,age,target_age,target)
lu |
A |
age |
A |
target_age |
A single positive |
target |
A single |
A discounted version of lu in the same format as the input.
Martin Jung
require(terra) # Load package example rasters range <- terra::rast(system.file( "extdata/example_range.tif", package = "insights", mustWork = TRUE )) lu <- terra::rast(system.file( "extdata/Grassland.tif", package = "insights", mustWork = TRUE )) lu <- lu / 10000 # Use sparse vegetation as a simple proxy for habitat age/maturity. # In real applications, use an age or maturity layer for the same land-use class. age <- terra::rast(system.file( "extdata/Grassland.tif", package = "insights", mustWork = TRUE )) age <- age / 10000 age <- age * 20 # Specify that habitat reaches 95% of full value at age 20. lu_discounted <- insights_discount(lu, age, target_age = 20, target = 0.95) out1 <- insights_fraction(range = range, lu = lu) out2 <- insights_fraction(range = range, lu = lu_discounted) op <- graphics::par(mfrow = c(1, 2)) terra::plot(out1, main = "Original grassland") terra::plot(out2, main = "Discounted grassland") graphics::par(op)require(terra) # Load package example rasters range <- terra::rast(system.file( "extdata/example_range.tif", package = "insights", mustWork = TRUE )) lu <- terra::rast(system.file( "extdata/Grassland.tif", package = "insights", mustWork = TRUE )) lu <- lu / 10000 # Use sparse vegetation as a simple proxy for habitat age/maturity. # In real applications, use an age or maturity layer for the same land-use class. age <- terra::rast(system.file( "extdata/Grassland.tif", package = "insights", mustWork = TRUE )) age <- age / 10000 age <- age * 20 # Specify that habitat reaches 95% of full value at age 20. lu_discounted <- insights_discount(lu, age, target_age = 20, target = 0.95) out1 <- insights_fraction(range = range, lu = lu) out2 <- insights_fraction(range = range, lu = lu_discounted) op <- graphics::par(mfrow = c(1, 2)) terra::plot(out1, main = "Original grassland") terra::plot(out2, main = "Discounted grassland") graphics::par(op)
Apply an area-of-habitat (AOH) refinement to a binary or fractional range
estimate using land-use or habitat layers expressed as fractions. Use this
method when the land-use values represent cell shares or suitability weights
in the interval [0, 1]. For land-use inputs already expressed as area
per cell, use insights_area() instead.
If lu has multiple layers or attributes, they are summed before being
applied to the range. This is useful when several land-use classes jointly
represent suitable habitat. Optional other layers can be supplied as
additional suitability or condition masks, but they must already be scaled to
[0, 1]; raw environmental layers such as elevation should be converted
to a suitability mask before calling this function.
Raster inputs are reprojected, cropped, and resampled to the range geometry
when needed. Temporal stars inputs may use a time or Time
dimension name. If outfile is supplied, the extension is adjusted to
.tif for raster output or .nc for stars output.
insights_fraction(range, lu, other, outfile = NULL, clamp = FALSE) ## S4 method for signature 'SpatRaster,SpatRaster,ANY,character,logical' insights_fraction(range,lu,other,outfile,clamp) ## S4 method for signature 'SpatRaster,stars,ANY,character,logical' insights_fraction(range,lu,other,outfile,clamp) ## S4 method for signature 'stars,stars,ANY,character,logical' insights_fraction(range,lu,other,outfile,clamp) ## S4 method for signature 'stars,SpatRaster,ANY,character,logical' insights_fraction(range,lu,other,outfile,clamp) ## S4 method for signature 'ANY,ANY,ANY,character,logical' insights_fraction(range,lu,other,outfile,clamp)insights_fraction(range, lu, other, outfile = NULL, clamp = FALSE) ## S4 method for signature 'SpatRaster,SpatRaster,ANY,character,logical' insights_fraction(range,lu,other,outfile,clamp) ## S4 method for signature 'SpatRaster,stars,ANY,character,logical' insights_fraction(range,lu,other,outfile,clamp) ## S4 method for signature 'stars,stars,ANY,character,logical' insights_fraction(range,lu,other,outfile,clamp) ## S4 method for signature 'stars,SpatRaster,ANY,character,logical' insights_fraction(range,lu,other,outfile,clamp) ## S4 method for signature 'ANY,ANY,ANY,character,logical' insights_fraction(range,lu,other,outfile,clamp)
range |
A |
lu |
A |
other |
Optional |
outfile |
A writeable |
clamp |
A |
Either a SpatRaster or temporal stars object or nothing if outputs are written directly to drive.
This function does not infer species-habitat relationships from raw land-use
classes. Select, weight, or transform land-use and condition layers before
calling insights_fraction().
Martin Jung
Rondinini, Carlo, and Piero Visconti. "Scenarios of large mammal loss in Europe for the 21st century." Conservation Biology 29, no. 4 (2015): 1028-1036.
Visconti, Piero, Michel Bakkenes, Daniele Baisero, Thomas Brooks, Stuart HM Butchart, Lucas Joppa, Rob Alkemade et al. "Projecting global biodiversity indicators under future development scenarios." Conservation Letters 9, no. 1 (2016): 5-13.
require(terra) # Load package example rasters range <- terra::rast(system.file( "extdata/example_range.tif", package = "insights", mustWork = TRUE )) lu <- c( terra::rast(system.file( "extdata/Grassland.tif", package = "insights", mustWork = TRUE )), terra::rast(system.file( "extdata/Sparsely.vegetated.areas.tif", package = "insights", mustWork = TRUE )) ) # Convert example land-use layers to fractions between 0 and 1. lu <- lu / 10000 out <- insights_fraction(range = range, lu = lu, clamp = TRUE) head(insights_summary(out))require(terra) # Load package example rasters range <- terra::rast(system.file( "extdata/example_range.tif", package = "insights", mustWork = TRUE )) lu <- c( terra::rast(system.file( "extdata/Grassland.tif", package = "insights", mustWork = TRUE )), terra::rast(system.file( "extdata/Sparsely.vegetated.areas.tif", package = "insights", mustWork = TRUE )) ) # Convert example land-use layers to fractions between 0 and 1. lu <- lu / 10000 out <- insights_fraction(range = range, lu = lu, clamp = TRUE) head(insights_summary(out))
This function handily summarizes the suitable habitat for a given species or biodiversity feature into an index. If a single timestep (or object with a single layer) is provided, this function simply summarizes the suitable area.
insights_summary( obj, toArea = TRUE, fun = "sum", relative = TRUE, symmetric = FALSE ) ## S4 method for signature 'SpatRaster,logical,character,logical,logical' insights_summary(obj,toArea,fun,relative,symmetric) ## S4 method for signature 'stars,logical,character,logical,logical' insights_summary(obj,toArea,fun,relative,symmetric)insights_summary( obj, toArea = TRUE, fun = "sum", relative = TRUE, symmetric = FALSE ) ## S4 method for signature 'SpatRaster,logical,character,logical,logical' insights_summary(obj,toArea,fun,relative,symmetric) ## S4 method for signature 'stars,logical,character,logical,logical' insights_summary(obj,toArea,fun,relative,symmetric)
obj |
A |
toArea |
A |
fun |
A |
relative |
A |
symmetric |
A |
When relative = TRUE, the standard relative change (in percent) is computed as
.
When symmetric = TRUE, the symmetric relative difference is also reported as
an additional column relative_change_sym:
This metric is bounded in and is preferred over the standard relative
change when the baseline habitat area is small (causing the standard
metric to become arbitrarily large), or when a bounded, symmetric index is needed
for cross-species comparisons. Requires the baseline suitability () to be
positive.
A data.frame with area estimates or the respective indicator.
Martin Jung
Baisero, Daniele, Piero Visconti, Michela Pacifici, Marta Cimatti, and Carlo Rondinini. "Projected global loss of mammal habitat due to land-use and climate change." One Earth 2, no. 6 (2020): 578-585.
Powers, Ryan P., and Walter Jetz. "Global habitat loss and extinction risk of terrestrial vertebrates under future land-use-change scenarios." Nature Climate Change 9, no. 4 (2019): 323-329.
require(terra) range <- terra::rast(system.file( "extdata/example_range.tif", package = "insights", mustWork = TRUE )) lu <- terra::rast(system.file( "extdata/Grassland.tif", package = "insights", mustWork = TRUE )) / 10000 out <- insights_fraction(range = range, lu = lu) insights_summary(out, relative = FALSE) ts <- c(out, out * 0.8, out * 0.6) terra::time(ts, tstep = "years") <- c(2020, 2040, 2060) insights_summary(ts, relative = TRUE, symmetric = TRUE)require(terra) range <- terra::rast(system.file( "extdata/example_range.tif", package = "insights", mustWork = TRUE )) lu <- terra::rast(system.file( "extdata/Grassland.tif", package = "insights", mustWork = TRUE )) / 10000 out <- insights_fraction(range = range, lu = lu) insights_summary(out, relative = FALSE) ts <- c(out, out * 0.8, out * 0.6) terra::time(ts, tstep = "years") <- c(2020, 2040, 2060) insights_summary(ts, relative = TRUE, symmetric = TRUE)
This function calculates the relative change of a vector, taking the first value as a reference value.
relChange(v, fac = 100)relChange(v, fac = 100)
v |
A |
fac |
A |
A numeric vector.
Martin Jung
# Example vector x <- c(20,6,2,1,15,25) relChange(x)# Example vector x <- c(20,6,2,1,15,25) relChange(x)
Computes the symmetric relative difference of a numeric vector with respect
to its first element. Unlike the standard relative change
(relChange), this metric is bounded in and
remains well-defined when the baseline value is small.
relChangeSym(v)relChangeSym(v)
v |
A |
The symmetric relative difference is defined as:
This formulation is preferred over the standard relative change when:
The baseline value is small, causing the standard formula
to produce arbitrarily large values (common for rare species or
freshly colonised habitat).
Symmetric treatment of gains and losses is required: a change from
to has the same magnitude (opposite sign) as from
to .
A bounded, directly comparable index across species or regions with very different baseline areas is needed.
A numeric vector of symmetric relative differences, bounded in
. Returns NA where the denominator
.
Martin Jung
x <- c(20, 6, 2, 1, 15, 25) relChangeSym(x)x <- c(20, 6, 2, 1, 15, 25) relChangeSym(x)
Clamp all cell values in a terra::SpatRaster or stars object to a
provided numeric interval. Values below the lower bound are set to the lower
bound, and values above the upper bound are set to the upper bound. Missing
values are preserved.
This is useful for keeping suitability, fractional land-use, or habitat
condition layers inside valid ranges before they are passed to functions such
as insights_fraction().
st_clamp(env, lb = -Inf, ub = Inf, lower = lb, upper = ub)st_clamp(env, lb = -Inf, ub = Inf, lower = lb, upper = ub)
env |
A |
lb |
A single |
ub |
A single |
lower |
Alias for |
upper |
Alias for |
For terra::SpatRaster inputs, st_clamp() delegates to
terra::clamp(). For stars inputs, each attribute array is clamped
directly with pmax() and pmin(), preserving the original dimensions
and attribute names.
An object of the same class as env, with values clamped to
[lb, ub].
Martin Jung
require(terra) r <- terra::rast(nrow = 2, ncol = 2, vals = c(-0.2, 0.4, 1.2, NA)) st_clamp(r, lower = 0, upper = 1) require(stars) s <- stars::st_as_stars(r) st_clamp(s, lower = 0, upper = 1)require(terra) r <- terra::rast(nrow = 2, ncol = 2, vals = c(-0.2, 0.4, 1.2, NA)) st_clamp(r, lower = 0, upper = 1) require(stars) s <- stars::st_as_stars(r) st_clamp(s, lower = 0, upper = 1)