cv_spatial: Use spatial blocks to separate train and test folds

View source: R/cv_spatial.R

cv_spatialR Documentation

Use spatial blocks to separate train and test folds

Description

This function creates spatially separated folds based on a distance to number of row and/or column. It assigns blocks to the training and testing folds randomly, systematically or in a checkerboard pattern. The distance (size) should be in metres, regardless of the unit of the reference system of the input data (for more information see the details section). By default, the function creates blocks according to the extent and shape of the spatial sample data (x e.g. the species occurrence), Alternatively, blocks can be created based on r assuming that the user has considered the landscape for the given species and case study. Blocks can also be offset so the origin is not at the outer corner of the rasters. Instead of providing a distance, the blocks can also be created by specifying a number of rows and/or columns and divide the study area into vertical or horizontal bins, as presented in Wenger & Olden (2012) and Bahn & McGill (2012). Finally, the blocks can be specified by a user-defined spatial polygon layer.

Usage

cv_spatial(
  x,
  column = NULL,
  r = NULL,
  k = 5L,
  hexagon = TRUE,
  flat_top = FALSE,
  size = NULL,
  rows_cols = c(10, 10),
  selection = "random",
  iteration = 100L,
  balance = TRUE,
  presence_bg = FALSE,
  user_blocks = NULL,
  folds_column = NULL,
  deg_to_metre = 111325,
  biomod2 = TRUE,
  offset = c(0, 0),
  extend = 0,
  seed = NULL,
  num_bins = 4L,
  plot = interactive(),
  report = interactive(),
  progress = interactive(),
  ...
)

Arguments

x

a simple features (sf) or SpatialPoints object of spatial sample data (e.g., species data or ground truth sample for image classification).

column

character (optional). Indicating the name of the column in which response variable (e.g. species data as a binary response i.e. 0s and 1s) is stored. It is used to report the number of records of each class/bin in every fold and, when balance = TRUE, to balance those classes across the folds. If column = NULL the response variable classes will be treated the same and only training and testing records will be counted (and balanced). This is used for binary (e.g. presence-absence/background) or multi-class responses (e.g. land cover classes for remote sensing image classification). Continuous numeric responses are binned into quantiles using num_bins before balancing.

r

a terra SpatRaster object (optional). If provided, its extent will be used to specify the blocks. It also supports stars, raster, or path to a raster file on disk.

k

integer value. The number of desired folds for cross-validation. The default is k = 5.

hexagon

logical. Creates hexagonal (default) spatial blocks. If FALSE, square blocks is created.

flat_top

logical. Creating hexagonal blocks with topped flat.

size

numeric value of the specified range by which blocks are created and training/testing data are separated. This distance should be in metres. The range could be explored by cv_spatial_autocor and cv_block_size functions. For residual-based block-size guidance, add model residuals to x and pass that residual column to cv_spatial_autocor.

rows_cols

integer vector. Two integers to define the blocks based on row and column e.g. c(10, 10) or c(5, 1). Hexagonal blocks uses only the first one. This option is ignored when size is provided.

selection

type of assignment of blocks into folds. Can be random (default), systematic, checkerboard, or predefined. The checkerboard does not work with hexagonal and user-defined spatial blocks. If the selection = 'predefined', user-defined blocks and folds_column must be supplied.

iteration

integer value. The number of attempts to create folds with balanced records. Only works when selection = "random".

balance

logical. When TRUE (default) and selection = "random", the folds are chosen from iteration random block assignments to balance the training/testing records (or the classes/bins of column when it is provided). If FALSE, a single random assignment is returned without balancing (equivalent to iteration = 1). This argument has no effect on the other selection methods.

presence_bg

logical; whether to treat column as species presence-background data (0s for background points and 1s for presences; see ‘Details’). When TRUE (with selection = "random" and balance = TRUE), the balancing search equalises only the presence (1s) records across folds so the many background points cannot dominate the objective; the blocks still contain all points but the background is ignored when scoring the balance. Requires a binary numeric column. The default is FALSE.

user_blocks

an sf or SpatialPolygons object to be used as the blocks (optional). This can be a user defined polygon and it must cover all the species (response) points. If selection = 'predefined', this argument and folds_column must be supplied.

folds_column

character. Indicating the name of the column (in user_blocks) in which the associated folds are stored. This argument is necessary if you choose the 'predefined' selection.

deg_to_metre

integer. The conversion rate of metres to degree. See the details section for more information.

biomod2

logical. Creates a matrix of folds that can be directly used in the biomod2 package as a CV.user.table for cross-validation.

offset

two number between 0 and 1 to shift blocks by that proportion of block size. This option only works when size is provided.

extend

numeric; This parameter specifies the percentage by which the map's extent is expanded to increase the size of the square spatial blocks, ensuring that all points fall within a block. The value should be a numeric between 0 and 5.

seed

integer; a random seed for reproducibility (although an external seed should also work).

num_bins

integer; the number of quantile bins used to stratify a continuous numeric column. The default is 4. Set num_bins = NULL to disable binning and treat every unique value as a separate class (the behaviour prior to version 3.3). If quantile breaks are tied, fewer bins may be used. The raw response values are not modified; bins are only used for fold balancing and record summaries.

plot

logical; whether to plot the final blocks with fold numbers in ggplot. Defaults to interactive(). You can re-create this with cv_plot.

report

logical; whether to print the report of the records per fold. Defaults to interactive().

progress

logical; whether to shows a progress bar for random fold selection. Defaults to interactive().

...

additional option for cv_plot.

Details

To maintain consistency, all functions in this package use meters as their unit of measurement. However, when the input map has a geographic coordinate system (in decimal degrees), the block size is calculated by dividing the size parameter by deg_to_metre (which defaults to 111325 meters, the standard distance of one degree of latitude on the Equator). In reality, this value varies by a factor of the cosine of the latitude. So, an alternative sensible value could be cos(mean(sf::st_bbox(x)[c(2,4)]) * pi/180) * 111325.

The offset can be used to change the spatial position of the blocks. It can also be used to assess the sensitivity of analysis results to shifting in the blocking arrangements. These options are available when size is defined. By default the region is located in the middle of the blocks and by setting the offsets, the blocks will shift.

Roberts et. al. (2017) suggest that blocks should be substantially bigger than the range of spatial autocorrelation (in model residual) to obtain realistic error estimates, while a buffer with the size of the spatial autocorrelation range would result in a good estimation of error. This is because of the so-called edge effect (O'Sullivan & Unwin, 2014), whereby points located on the edges of the blocks of opposite sets are not separated spatially. Blocking with a buffering strategy overcomes this issue (see cv_buffer). When using cv_spatial_autocor to inform size, note that response or covariate variograms are exploratory proxies for residual autocorrelation unless model residuals have been added to x and supplied through the column argument.

For presence-background data (presence_bg = TRUE), column holds 1 for presences and 0 for background points – locations sampled across the study area to represent the available conditions rather than confirmed absences. The fold balancing then targets only the presence records (the blocks still contain all points), so the abundant background cannot dominate the split.

Value

An object of class S3. A list of objects including:

  • folds_list - a list containing the folds. Each fold has two vectors with the training (first) and testing (second) indices

  • folds_ids - a vector of values indicating the number of the fold for each observation (each number corresponds to the same point in species data)

  • biomod_table - a matrix with the folds to be used in biomod2 package

  • k - number of the folds

  • size - input size, if not null

  • block_shape - the block geometry used: "hexagon", "square", or "user-defined"

  • selection - how blocks were assigned to folds: "random", "systematic", "checkerboard", or "predefined"

  • column - the name of the column if provided

  • blocks - spatial polygon of the blocks

  • records - a table with the number of points in each category of training and testing

References

Valavi, R., Elith, J., Lahoz-Monfort, J. J., & Guillera-Arroita, G. (2019). blockCV: An R package for generating spatially or environmentally separated folds for k-fold cross-validation of species distribution models. Methods in Ecology and Evolution, 10(2), 225-232. doi:10.1111/2041-210X.13107.

Bahn, V., & McGill, B. J. (2012). Testing the predictive performance of distribution models. Oikos, 122(3), 321-331.

O'Sullivan, D., Unwin, D.J., (2010). Geographic Information Analysis, 2nd ed. John Wiley & Sons.

Roberts et al., (2017). Cross-validation strategies for data with temporal, spatial, hierarchical, or phylogenetic structure. Ecography. 40: 913-929.

Wenger, S.J., Olden, J.D., (2012). Assessing transferability of ecological models: an underappreciated aspect of statistical validation. Methods Ecol. Evol. 3, 260-267.

See Also

cv_buffer and cv_cluster; cv_spatial_autocor and cv_block_size for selecting block size; cv_plot to visualise, and cv_distance and cv_similarity to evaluate, the folds

For CV.user.table see BIOMOD_Modeling in biomod2 package

Examples


library(blockCV)

# import presence-absence species data
points <- read.csv(system.file("extdata/", "species.csv", package = "blockCV"))
# make an sf object from data.frame
pa_data <- sf::st_as_sf(points, coords = c("x", "y"), crs = 7845)

# hexagonal spatial blocking by specified size and random assignment
sb1 <- cv_spatial(x = pa_data,
                  column = "occ",
                  size = 450000,
                  k = 5,
                  selection = "random",
                  iteration = 50)

# spatial blocking by row/column and systematic fold assignment
sb2 <- cv_spatial(x = pa_data,
                  column = "occ",
                  rows_cols = c(8, 10),
                  k = 5,
                  hexagon = FALSE,
                  selection = "systematic")



blockCV documentation built on Aug. 20, 2026, 5:10 p.m.