--- title: "0. Loading and exploring spatiotemporal data" output: rmarkdown::html_vignette vignette: > %\VignetteIndexEntry{0. Loading and exploring spatiotemporal data} %\VignetteEngine{knitr::rmarkdown} %\VignetteEncoding{UTF-8} --- ```{r, include = FALSE} knitr::opts_chunk$set(collapse = TRUE, comment = "#>", fig.width = 6, fig.height = 4.5) ``` ```{r setup} library(sptrends) ``` ## Why this matters sptrends analyses spatiotemporal trends in gridded environmental data. These datasets commonly exhibit serial correlation and spatial dependence, while analysing many cells simultaneously creates a large-scale multiple-testing problem. Because these challenges interact to affect statistical inference, sptrends keeps the main analytical stages explicit and separate: serial-correlation assessment and treatment, trend testing, slope estimation and multiple-testing correction. These stages may be used independently or combined within complete analytical workflows. This is not simply a sequence of steps assembled for convenience. True Significant Trends (TST), introduced by [Gutiérrez-Hernández and García (2025)](https://doi.org/10.1016/j.rsase.2024.101377), is the methodological origin of this design: it identified these three challenges as interconnected facets of the same underlying problem, not as separate issues to be patched independently, and sptrends inherits that understanding rather than just its pipeline. This vignette shows how to recognise, inspect and visualise the input, and how the main analytical stages fit together. Later vignettes explain each methodological decision. ## What `read_ordered_stack()` and `read_netcdf_stack()` do The usual analytical input is a `terra::SpatRaster` with one layer per time step, ordered from earliest to latest. It can be created from chronologically ordered raster files with `read_ordered_stack()` or imported from NetCDF datasets with `read_netcdf_stack()`. Across these layers, each valid raster cell defines an individual time series embedded within a spatially structured dataset. Analytical results are returned as structured `sptrends` objects with familiar `print()`, `summary()` and `plot()` methods. ## Basic workflow The bundled example is an annual NDVI series derived from the [NOAA STAR Blended Vegetation Health Product (Blended-VHP)](https://www.star.nesdis.noaa.gov/smcd/emb/vci/VH/vh_ftp.php). The data were spatially resampled to a coarser 100 km resolution to enable faster execution of the examples and reprojected to an [Eckert IV](https://map-projections.net/compare.php?p1=eckert-4&p2=equalearth&w=1&sm=1&d=1) equal-area grid so that every raster cell represents the same surface area. An equal-area projection is not required by sptrends, but this consideration is often overlooked and becomes important when interpreting cell counts, spatial proportions or area-based summaries. ```{r} r <- read_ordered_stack(example_data("vhp_ndvi")) r terra::nlyr(r) terra::time(r) ``` The imported object contains 42 annual observations spanning 1982--2023. Before beginning any trend analysis, it is good practice to verify that the temporal ordering has been detected correctly and that the raster series matches the expected study period. Start by viewing the complete series and checking the temporal order: ```{r, fig.width = 10, fig.height = 11, fig.alt = "Mosaic of all annual mean NDVI layers in temporal order"} ndvi_col <- rev(grDevices::hcl.colors(50, "Greens 3")) terra::plot( r, col = ndvi_col, colNA = "transparent", nc = 6, maxnl = terra::nlyr(r) ) ``` The same layers can be displayed sequentially in an interactive R session: ![Annual mean NDVI, 1982--2023](figures/ndvi-annual-animation.gif) The embedded animation uses the same 42 layers shown in the mosaic. To reproduce it interactively from the original raster series, run: ```{r, eval = FALSE} terra::animate( r, pause = 0.2, main = as.character(terra::time(r)), col = ndvi_col, colNA = "transparent" ) ``` ## Understanding the results ### Declaring seasonal input For seasonal data, supply files in their known chronological order. A file may contain several layers; `time` must contain one value per layer. ```{r explicit-input, eval = FALSE} # ordered_files is your chronological vector of file paths. monthly <- read_ordered_stack( files = ordered_files, cycle_type = "monthly", start = as.Date("2001-08-01"), report = FALSE ) seasonal <- compute_anomalies(monthly, cycle_type = "monthly", start_position = 8) result <- workflow_trends(seasonal$anomalies, report = FALSE) ``` `start` is the beginning of the first period. Monthly and composite periods use their centre as the default assigned date; annual layers always use 1 January. Optional `end` must be the inclusive end of the last period and checks the expected layer count. For other calendars, use `read_ordered_stack(files = ordered_files, time = layer_dates)`. `compute_anomalies()` uses positions, not date metadata. Supply the cycle length and the first position correctly: August is position 8 in a monthly annual cycle. Its `climatology` and optional `climatology_sd` are ordered from position 1 to `cycle`; `$anomalies` retains the input layer order. Daily input with leap days does not have a fixed 365-position annual cycle. The anomaly result is a plain list of rasters. Pass `$anomalies` to the next analytical step or inspect a component with `terra::plot()`. ### Analytical outputs So far you have only looked at the raw data. Once an analytical function has actually been run -- in any of the vignettes that follow -- its output presents itself the same way throughout the package: analytical functions return structured objects with familiar `print()`, `summary()` and `plot()` methods. Complete workflows retain their intermediate results, so users can examine every analytical stage rather than treating the workflow as a black box. ## Choosing the main options | Your question | Where to continue | | --- | --- | | Is temporal dependence a problem? | [Prewhitening vignette](b-prewhitening.html) | | Is there evidence of a trend? | [Trend-test vignette](c-trend-test.html) | | How large is the change? | [Slope-estimation vignette](d-slope-estimation.html) | | Which findings survive multiple testing? | [Multiple-testing vignette](e-fdr-correction.html) | | How do I combine the stages? | [Trend-workflows vignette](g-workflow-trends.html) | ## Common mistakes - Do not assume layers are in chronological order; confirm it directly before analysis. - Do not treat missing-value codes as valid observations. - Do not interpret raster-cell counts or proportions as surface area without considering the projection and cell size; use an equal-area grid when area-based comparisons or summaries are required. - Do not assume that observations are independent, whether across time (serial correlation, see [prewhitening vignette](b-prewhitening.html)) or across neighbouring cells (spatial dependence, see [trend-test vignette](c-trend-test.html)); both are common in gridded environmental time series and affect inference. - Do not treat cell-wise tests as isolated analyses; testing many raster cells simultaneously creates a large-scale multiple-testing problem (see [multiple-testing vignette](e-fdr-correction.html)). ## Next steps Continue to [`vignette("b-prewhitening")`](b-prewhitening.html), or go directly to [`vignette("c-trend-test")`](c-trend-test.html) if temporal preprocessing is unnecessary. ## Further details See `?sptrends` for the function index and quality-assurance protocol, `?read_ordered_stack` and `?read_netcdf_stack` for data import, and `?inspect_ts_cell` for interactive exploration. ## References - Gutiérrez-Hernández, O. and García, L.V. (2025) Uncovering True Significant Trends in Global Greening. *Remote Sensing Applications*, 101377. https://doi.org/10.1016/j.rsase.2024.101377