This article gives a first tour of the main insights_*()
functions. The examples use the small rasters shipped with the package
so they can be rendered by pkgdown without external downloads.
| Function | Use it when | Main output |
|---|---|---|
insights_fraction() |
Land-use, habitat, or condition layers are fractions or suitability
weights in [0, 1]. |
A refined suitability or area-of-habitat raster. |
insights_area() |
Land-use or habitat layers are already expressed as area per cell. | A refined raster already in area units. |
insights_discount() |
A habitat class should be discounted by an age or maturity layer. | A maturity-weighted version of the land-use layer. |
insights_summary() |
Refined rasters need to be converted to totals or relative indicators. | A data frame of absolute area, relative change, or symmetric relative change. |
Example inputs
The current range example is a binary range layer. The land-use
layers are stored as integer fractions from 0 to 10000, so we divide
them by 10000 before passing them to insights_fraction().
The DEM example is already scaled to [0, 1] and is used
here as a simple additional suitability mask.
range <- terra::rast(system.file(
"extdata/example_range.tif",
package = "ibis.insights",
mustWork = TRUE
))
grassland <- terra::rast(system.file(
"extdata/Grassland.tif",
package = "ibis.insights",
mustWork = TRUE
)) / 10000
sparse_vegetation <- terra::rast(system.file(
"extdata/Sparsely.vegetated.areas.tif",
package = "ibis.insights",
mustWork = TRUE
)) / 10000
lu_fraction <- c(grassland, sparse_vegetation)
names(lu_fraction) <- c("grassland", "sparse_vegetation")
extra_suitability <- terra::rast(system.file(
"extdata/DEM.tif",
package = "ibis.insights",
mustWork = TRUE
))
names(extra_suitability) <- "extra_suitability"
op <- par(mfrow = c(2, 2), mar = c(2, 2, 3, 4))
plot(range, main = "Range")
plot(lu_fraction[[1]], main = "Grassland fraction")
plot(lu_fraction[[2]], main = "Sparse vegetation fraction")
plot(extra_suitability, main = "Additional suitability mask")
par(op)Fractional land-use: insights_fraction()
Use insights_fraction() when the habitat or land-use
input is a fraction, probability, or suitability weight. Multiple
land-use layers are summed before they are applied to the range.
clamp = TRUE caps the combined suitability at one when
several suitable land-use classes overlap.
aoh_fraction <- insights_fraction(
range = range,
lu = lu_fraction,
other = extra_suitability,
clamp = TRUE
)
plot(aoh_fraction, main = "Fractional InSiGHTS output")
insights_summary() converts this fractional raster to
area by multiplying by cell area, because toArea = TRUE by
default.
insights_summary(aoh_fraction, relative = FALSE)
#> time suitability unit
#> 1 NA 23590.72 km2Areal land-use: insights_area()
Use insights_area() when the land-use values are already
in area units. In this example we convert the fractional land-use layers
to square kilometres per cell with terra::cellSize().
Because the output is already in area units, summarize with
toArea = FALSE.
cell_area_km2 <- terra::cellSize(lu_fraction[[1]], unit = "km")
lu_area_km2 <- lu_fraction * cell_area_km2
aoh_area <- insights_area(
range = range,
lu = lu_area_km2,
other = extra_suitability
)
plot(aoh_area, main = "Areal InSiGHTS output (km2 per cell)")
insights_summary(aoh_area, toArea = FALSE, relative = FALSE)
#> time suitability unit
#> 1 NA 23590.72 inputMaturity weighting: insights_discount()
Use insights_discount() before
insights_fraction() or insights_area() when a
habitat class should not count at full value immediately after it
appears. The example below creates a simple dummy age layer for
grassland. Real analyses should use an age or maturity layer for the
same habitat class.
grassland_age <- lu_fraction[["grassland"]] * 40
names(grassland_age) <- "grassland_age_years"
invisible(utils::capture.output({
grassland_discounted <- insights_discount(
lu = lu_fraction[["grassland"]],
age = grassland_age,
target_age = 20,
target = 0.95
)
}))
names(grassland_discounted) <- "grassland_discounted"
lu_discounted <- c(grassland_discounted, lu_fraction[["sparse_vegetation"]])
names(lu_discounted) <- c("grassland_discounted", "sparse_vegetation")
aoh_discounted <- insights_fraction(
range = range,
lu = lu_discounted,
other = extra_suitability,
clamp = TRUE
)
op <- par(mfrow = c(1, 3), mar = c(2, 2, 3, 4))
plot(lu_fraction[["grassland"]], main = "Original grassland")
plot(grassland_age, main = "Dummy age layer")
plot(grassland_discounted, main = "Discounted grassland")
par(op)
op <- par(mfrow = c(1, 2), mar = c(2, 2, 3, 4))
plot(aoh_fraction, main = "Without discount")
plot(aoh_discounted, main = "With grassland discount")
par(op)
insights_summary(aoh_discounted, relative = FALSE)
#> time suitability unit
#> 1 NA 11646.5 km2Indicators: insights_summary()
With a single-layer raster, insights_summary() reports
an absolute total. With multiple layers or time steps, it can also
report change relative to the first time step. The standard relative
change and symmetric relative change are both returned as fractions; the
symmetric relative change is bounded in [-1, 1].
aoh_series <- c(aoh_fraction, aoh_discounted, aoh_discounted * 0.8)
names(aoh_series) <- c("baseline", "maturity_discount", "future_example")
terra::time(aoh_series, tstep = "years") <- c(2020, 2040, 2060)
index_summary <- insights_summary(
aoh_series,
relative = TRUE,
symmetric = TRUE
)
index_summary
#> time suitability unit relative_change relative_change_sym
#> 1 2020 0.00 km2 0.0000000 0.0000000
#> 2 2040 -11944.22 km2 -0.5063101 -0.3389660
#> 3 2060 -14273.52 km2 -0.6050481 -0.4337412
plot(
index_summary$time,
index_summary$relative_change,
type = "b",
pch = 19,
xlab = "Year",
ylab = "Relative change",
main = "InSiGHTS index relative to 2020"
)
abline(h = 0, lty = 2, col = "grey50")
Temporal scenario example
The package also ships a small temporal scenario for Bombina
bombina. This is a stars object with a time dimension
and an ensemble_threshold attribute. It is useful for
demonstrating how the insights_*() functions handle
temporal range inputs.
bombina_range <- stars::read_mdim(system.file(
"extdata/Bombina_bombina__ssp126.nc",
package = "ibis.insights",
mustWork = TRUE
))
bombina_range <- split(bombina_range)
bombina_range <- bombina_range["ensemble_threshold"]
invisible(utils::capture.output({
bombina_aoh <- suppressMessages(insights_fraction(
range = bombina_range,
lu = lu_fraction,
clamp = TRUE
))
}))
bombina_summary <- insights_summary(
bombina_aoh,
relative = TRUE,
symmetric = TRUE
)
bombina_summary
#> time band suitability unit relative_change relative_change_sym
#> 1 2015-01-01 2015-01-01 0.000 km2 0.00000000 0.00000000
#> 2 2025-01-01 2025-01-01 -1760.229 km2 -0.02073683 -0.01047704
#> 3 2035-01-01 2035-01-01 -9637.467 km2 -0.11353665 -0.06018492
#> 4 2045-01-01 2045-01-01 -7887.350 km2 -0.09291895 -0.04872312
#> 5 2055-01-01 2055-01-01 -9587.168 km2 -0.11294409 -0.05985201
#> 6 2065-01-01 2065-01-01 -13247.307 km2 -0.15606329 -0.08463593
#> 7 2075-01-01 2075-01-01 -12746.687 km2 -0.15016560 -0.08117786
#> 8 2085-01-01 2085-01-01 -15312.780 km2 -0.18039612 -0.09914033
#> 9 2095-01-01 2095-01-01 -16806.513 km2 -0.19799342 -0.10987386
bombina_aoh_raster <- terra::rast(bombina_aoh)
terra::time(bombina_aoh_raster) <- stars::st_get_dimension_values(
bombina_aoh,
"time"
)
op <- par(mfrow = c(1, 3), mar = c(2, 2, 3, 4))
plot(bombina_aoh_raster[[1]], main = "2015")
plot(bombina_aoh_raster[[5]], main = "2055")
plot(bombina_aoh_raster[[9]], main = "2095")
par(op)
plot(
as.Date(bombina_summary$time),
bombina_summary$relative_change,
type = "b",
pch = 19,
xlab = "Year",
ylab = "Relative change",
main = "Temporal InSiGHTS index"
)
abline(h = 0, lty = 2, col = "grey50")
