Storing nested spatial output with tar_terra_nested(): a MESS example
Source:vignettes/mess-tar-terra-nested.Rmd
mess-tar-terra-nested.RmdSome functions return a list of
terra::SpatRaster objects rather than a single raster. The
geotargets
package can serialize individual SpatRaster objects, but
not a list that contains several of them.
tar_terra_nested() fills this gap by recursively finding
and serializing every spatial object inside an arbitrary R
structure.
A natural example is bssdm::mess(), which calculates
Multivariate Environmental Similarity Surfaces. With
full = TRUE it returns a MessResult list of
four SpatRaster layers: mess,
mess_by_variable, mod, and
mos.
This vignette keeps things lightweight: rather than downloading
global climate data via geodata, it builds a small
synthetic three-variable raster so the example runs in a fraction of a
second and requires no network access.
library(targets)
library(bssdm)
tar_dir({
# tar_dir() runs the pipeline in a temporary directory.
tar_script({
library(targets)
library(geotargets)
library(terra)
library(bssdm)
library(targets.utils)
# Build a small synthetic climate raster and compute MESS against a
# sample of reference cells. Everything is generated in-memory, so no
# data is downloaded.
make_mess <- function() {
set.seed(4172)
r <- rast(
nrows = 20, ncols = 20, nlyrs = 3,
xmin = 0, xmax = 10, ymin = 0, ymax = 10
)
names(r) <- c("bio1", "bio12", "bio5")
values(r) <- cbind(
runif(ncell(r), 5, 25), # mean temperature
runif(ncell(r), 200, 2000), # annual precipitation
runif(ncell(r), 20, 40) # max temperature
)
# Reference values drawn from a random sample of cells
ref <- spatSample(
r, size = 30, method = "random",
as.df = TRUE, na.rm = TRUE
)
# mess() returns a MessResult: a list of several SpatRasters
mess(r, ref, full = TRUE)
}
list(
# tar_terra_nested() handles the list of rasters that tar_target()
# alone could not serialize.
tar_terra_nested(
mess_result,
make_mess()
)
)
})
tar_make()
# Read the target back: the MessResult list is reconstructed, with each
# SpatRaster restored from its own file on disk.
x <- tar_read(mess_result)
print(class(x))
print(names(x))
x$mess
# Plot the MESS result
plot(x)
})
#> terra 1.9.34
#> + mess_result dispatched
#> ✔ mess_result completed [159ms, 4.32 kB]
#> ✔ ended pipeline [380ms, 1 completed, 0 skipped]
#> [1] "MessResult" "list"
#> [1] "mess" "mess_by_variable" "mod" "mos"
#> [plot mode] fit legend/component: Some legend items or map compoments do not
#> fit well, and are therefore rescaled.
#> ℹ Set the tmap option `component.autoscale = FALSE` to disable rescaling.
The reconstructed object retains its original MessResult
class and all four SpatRaster layers, each transparently
restored from disk. The same approach works for any function that
returns spatial objects nested inside lists, data frames, or other R
structures.