Heterra

Part 3 · Spatial pattern · Chapter 4

SDA

Second dimension of spatial association

The question

Does what surrounds a sample, and not only what lies at the sample, help to predict my variable, and by how much?

You need

Two layers: samples with a numeric response y, and a grid of cells around them with the covariates as fields.

You get

New variables from each covariate's neighbourhood, the stable ones among them, prediction maps with and without them, and a cross-validation of their gain.

1The method

The idea

A covariate read at a sample's location says nothing about what surrounds it. SDA (Song 2022) summarises each covariate in the grid cells around every sample. Each buffer radius and each quantile gives one new variable:

SDA variable = the quantile τ of a covariate over the grid cells closer than b km to the sample
b is the buffer radius (the searching range) and τ lies between 0 and 1: τ = 0 is the minimum of the neighbourhood, 0.5 its median, 1 its maximum. The variable is named after all three, for example NDVI_b5t0.3.

The variables multiply quickly: 8 covariates × 5 buffers × 11 quantiles = 440 in the example. Most of them carry the same information, so SDA in Heterra has three parts, and the last one is the test.

Concept of SDA: in the first dimension a sample is linked to covariate values at points; in the second dimension it is linked to all the covariate data in an area around it
How the method works. Above, the first dimension: the response at a sample is linked to covariate values at the same points. Below, the second dimension: a cone opens from the sample onto the covariate surface, and the data inside the circle are summarised. In this way, locations that were never sampled enter the model. Source: Song (2022), Fig. 1.

The three parts

PartQuestionResult
ScalesWhat does each covariate look like around every sample?One variable per covariate, buffer and quantile, and a catalogue that says what each one measures
Variable selectionWhich of them are ranked highly in a stable way?At most one variable per covariate, chosen with the selection of GCF: random forests on resampled spatial blocks
Prediction and cross-validationWhat do they change on the map, and do they predict better?Maps from a random forest with the raw covariates (the baseline, X) and with the selected variables added (X + SDA); R² of both in spatial and random folds

When to use it

Where it has been used

FieldResponse ySpatial unitStudy
Soil geochemistryConcentration of Cr and Cu in soilSoil sample pointSong (2022)
Urban parksSentiment score from volunteered textUrban parkWang et al. (2026)
Crop productionWheat productionLocal government areaRen, Song and Yu (2026), with outliers in place of quantiles: see SDO

Any response measured at locations fits, if a dense grid of covariates covers the area around them.

Keep in mindA selected variable is stable, and stability is not evidence of prediction. Whether the variables help is the cross-validation's question, and its answer can be "not clearly". R² is always 1 − SSE/SST.

2In Heterra

2.1 Prepare your data

Two layers (Part 1 shows how to add data). The samples have one row per observation. The grid has cells around the samples, with the covariates as fields.

Layer or fieldTypeIn the example
SamplesPoints, polygons or, since version 1.6.0, a table894 soil Zn samples
Response yNumber, in the sampleslog_Zn = log(Zn), prepared as a field, because SDA does not transform y
GridGrid cells, points or polygons13,132 cells of 1 km
CovariatesNumbers, fields of the gridElevation, Slope, Aspect, Water, NDVI, pH, SOC, Road
Boundary (optional)A polygon layersda_boundary: the outline on the prediction maps, which show only the cells inside it. It changes no result.

The covariates may also be fields of the samples, under the same names. A sample without a covariate's field gets the value of the nearest grid cell that has one, and the catalogue says so. The example is the data of the GOS tutorial, from the Leonora district, Western Australia.

2.2 Run the example, step by step

Open the tool from the Toolbox (Spatial pattern → SDA), click Tutorial, then Load Example. The samples, the grid and the boundary appear on the map, and the panel on the right is filled in for you.

Heterra after Load Example: the covariate grid and the boundary on the map and the SDA panel at step 1
After Load Example: the three layers on the left, the grid on the map, the SDA panel on the right at step 1 of 5.

The panel has five steps, and three of them compute: steps 2, 4 and 5 each have a Run button, and each run needs the one before it. A tick on a step's number says that it has been run. The pictures show the panel after the runs.

  1. SDA panel, step 1 CovariatesCovariatesChoose the Samples, the Grid and the eight covariates. Click Next.
  2. SDA panel, step 2 ScalesScalesKeep the buffers 1, 3, 5, 7, 9 km and the quantiles 0, 0.1, …, 1. Click Run: a copy of the samples gets 440 new fields.
  3. SDA panel, step 3 Modelling dataModelling dataThat copy, the catalogue of step 2 and y = log_Zn. The eight covariates are the Original covariates (X); all 440 are ticked under Generated variables.
  4. SDA panel, step 4 Variable selectionVariable selectionBlock size 50 km, B = 10 resamples. Click Run; it cannot be skipped, because step 5 runs after it.
  5. SDA panel, step 5 Prediction and cross-validationPrediction and cross-validation5 folds, Spatial blocks and Random. Click Run (a few seconds).

The tutorial uses B = 10 resamples, 100-tree selection forests and 200-tree random forests to stay quick; the defaults are B = 80, 200 and 500 trees. After the selection the Chart page shows the selected variables, and after the last run the prediction maps. The panel lists the results under Outputs, and a green line says that they match the reference results computed with R.

Heterra after the last SDA run: the two prediction maps on the Chart page and the results in the panel
After the last Run: the prediction maps. The menu above the figure opens the other figures; steps 2, 4 and 5 are ticked.

2.3 With your own data

  1. Add the samples and the grid (Add Data), open SDA from the Toolbox and choose them in step 1. The grid needs every covariate as a field.
  2. Choose the buffers for the distances at which you expect the surroundings to act, in km. Variables multiply (covariates × buffers × quantiles): with few samples, use fewer.
  3. Choose a block size that leaves several blocks per fold (here 50 km gives 8 blocks). With fewer blocks than folds, some folds stay empty.
  4. Keep the defaults for real analyses: B = 80, 200 selection trees, 500 random-forest trees.

3Reading the results

Read the results in this order: the selected variables (what was kept, and at which scale?), the prediction maps (what do they change?), then the cross-validation and the folds table (is the change an improvement?), and last the scatter of observed against predicted values.

3.1 Selected variables

Selected variables: two blue bubbles, NDVI at searching range 5 km and quantile 0.3, Water at 9 km and quantile 0.5
Selected variables: one bubble per selected variable, at its searching range b and quantile τ, labelled with its covariate.

What it shows. The variables the selection kept. The area of a bubble is |r| and its colour the sign of r, where r is the correlation between the variable and y over the samples (table Selected variables and their correlation with y). The eight raw covariates are always kept and are not drawn.

VariableCovariateb (km)τrFrequency
NDVI_b5t0.3NDVI50.3−0.411.0
Water_b9t0.5Water90.5−0.350.4

How to read it. A covariate's variables form one group, and each group that passes keeps one variable. Two of the eight groups passed the threshold π = 0.6 here. The table Selected variables gives every variable's frequency: the share of the resamples in which it was among the 20 most important generated variables. NDVI_b5t0.3 was there in all ten. For Water the group passed (one of its variables was there in 8 of 10 resamples) and Water_b9t0.5 itself in 4 of 10. Several other NDVI variables also have a frequency of 1.0 (NDVI_b5t0.4, NDVI_b7t0.5, NDVI_b9t0.2), so read the result as "NDVI within about 5 to 9 km, lower to middle quantiles" and not as one exact scale.

In a paper

"Second-dimension variables were generated as quantiles (τ = 0, 0.1, …, 1) of eight covariates within 1, 3, 5, 7 and 9 km of each sample (Song 2022), 440 in total. The stability selection kept two: the 0.3 quantile of NDVI within 5 km (r = −0.41 with log Zn) and the median of Water within 9 km (r = −0.35)."

3.2 Prediction maps

Two maps of predicted log_Zn on one colour scale: a, the SDA prediction; b, the baseline prediction
Prediction maps: a, the SDA prediction (X + SDA); b, the baseline (X only), on one colour scale.

What it shows. Two random forests fitted on all samples and applied to every grid cell. The selected variables are generated at the cells as they were at the samples; a cell lies at distance 0 from itself, so it is in its own neighbourhoods. A new layer on the map holds pred_base, pred_sda and pred_diff; a cell with a missing value of a model variable is empty.

How to read it. Both maps have the same broad pattern: high predicted values in the centre and the south-east. Map a is smoother and its high areas are more compact, because its two extra variables are neighbourhood summaries; map b is more speckled. The maps show what the variables change, not that the change is right: that is the R² chart's question.

In a paper

"Figure X compares the prediction of log Zn from the eight covariates alone with the prediction that adds the two second-dimension variables. Both show the same main pattern; the second is spatially smoother."

3.3 Cross-validated R²

Bar charts of mean R² over folds with SD bars, baseline against X + SDA, for spatial-block folds and random folds
Cross-validated R²: a, spatial-block folds; b, random folds. Bars are the mean over five folds, lines ± SD.

What it shows. For each kind of fold, the baseline against X + SDA: mean R² over the folds (R² = 1 − SSE/SST) ± SD, with the change written above the bars as a percentage of the baseline. The selection is repeated in every fold, so the test samples never choose the variables.

FoldsR² baseline (SD)R² X + SDA (SD)RMSE baselineRMSE X + SDA
Spatial blocks0.076 (0.208)0.141 (0.238)0.6900.661
Random0.348 (0.083)0.388 (0.076)0.6420.623

How to read it. The spatial gain is large in per cent (+86.3%) because the baseline is small, and the fold SDs (about 0.2) are larger than the gain (0.065). Read the table Cross-validation by fold before quoting a percentage:

Spatial foldTest samplesR² baselineR² X + SDA
12350.0750.054
21660.1850.317
32970.1790.312
41680.2220.260
528−0.284−0.239

X + SDA is higher in four of the five spatial folds and lower in one. Fold 5 has only 28 test samples and a negative R² for both models (worse than predicting the mean); it pulls both means down and makes the SDs large. Spatial folds are the stricter test, because the test samples lie in blocks the model has not seen; random folds give higher values for both models. With the defaults (B = 80, 200 and 500 trees) the result is close: spatial 0.076 → 0.152, random 0.343 → 0.391.

Not the published resultThe public SDA code reports R² 0.3325 against 0.2752 for the paper's Cr case, with VIF selection and one 70/30 split. Here the selection is GCF's and the validation K-fold, on another data set, so the numbers do not compare.

In a paper

"In five-fold cross-validation with 50 km spatial blocks, adding the second-dimension variables raised the mean R² from 0.076 (SD 0.208) to 0.141 (SD 0.238), and in random folds from 0.348 (SD 0.083) to 0.388 (SD 0.076). The model with the variables was better in four of five spatial folds, but the gain is smaller than the variation between folds."

3.4 Observed vs predicted

Scatter of observed log_Zn against the out-of-fold predictions of X + SDA in spatial blocks, with the 1:1 line; R² = 0.273
Observed vs predicted: the out-of-fold predictions of X + SDA in the spatial-block folds, with the 1:1 line.

What it shows. One point per sample: its observed y against the prediction made when its fold was left out. The printed R² (0.273) is pooled over all out-of-fold values.

How to read it. The pooled R² (0.273; baseline 0.199) is not the mean over folds (0.141): the pooled value is computed once over all 894 predictions, the fold mean gives each fold the same weight, and so the small fold 5 counts for a fifth of it. Say which one you report. The predictions cover a narrower range (about 2.4 to 4.6) than the observations (about 0.7 to 5.9): the lowest observed values are over-predicted and the highest under-predicted.

Export any figure from the Chart page as PDF, SVG or PNG; Data CSV saves the numbers behind it. Export results in the panel writes a report of the run (Part 1).

3.5 Reading the results together

The outputs make one argument in three steps: the surroundings of the samples hold information (which covariate, at which range and quantile), that information changes the map (where), and the cross-validation says whether the change is an improvement. Read them in this order:

  1. Selected variables: which covariates, searching ranges and quantiles were kept, and whether the quantiles are extremes or middles of the neighbourhood.
  2. Prediction maps: what the selected variables change, and where.
  3. Cross-validated R², with the table Cross-validation by fold: the gap between X + SDA and the baseline, and whether it holds in most folds.
  4. Observed vs predicted: which part of the range of y is predicted well.

What SDA is notIt is not a model of spatial autocorrelation and it does not interpolate the response: the values of y at neighbouring samples are never used. It adds variables on the explanatory side only. It can therefore be combined with kriging, as the published case does; that step is outside Heterra.

3.6 From the results to a manuscript

SectionWhat to writeFrom Heterra
MethodsThe definition of the variable (the quantile τ within the searching range b); the buffers and quantiles that were searched; the selection rule and its settings; the folds and the block sizeThe settings of the run (in the exported report)
ResultsFollow the order of the run: which (b, τ) were selected, what they change on the map, X + SDA against the baseline on left-out samples. Every finding has a numberFigures Selected variables, Prediction maps, Cross-validated R² and Observed vs predicted; tables Selected variables and their correlation with y and Cross-validation by fold
DiscussionThe scale that the selected searching ranges point to; why these quantiles and not others; the size of the gain beside the variation between folds; the computing costTable Selected variables (the frequencies of the neighbouring variables); table Cross-validation by fold
Common pitfalls
  • The selection must not see the test samples. Heterra repeats it in every fold, so report the cross-validated R², not the fit of a model on all samples.
  • Check how many grid cells lie inside the smallest buffer. The quantiles τ = 0 and τ = 1 over a few cells are noise.
  • The generated variables are collinear by construction: neighbouring buffers and neighbouring quantiles describe almost the same neighbourhood. Do not skip the selection, and do not read one selected (b, τ) as an exact scale.

4Exercises

Exercises 1 to 3 use the example. Exercise 4 is for your own data.

Exercise 1Read

Run the example with its settings. Which SDA variables are selected, at which searching range and quantile, and what is the sign of their correlation with log_Zn? How many variables does the X + SDA model have in all?

Answer

NDVI_b5t0.3 (5 km, τ = 0.3, r = −0.41) and Water_b9t0.5 (9 km, τ = 0.5, r = −0.35), both negative. With the eight raw covariates, which are always kept, the model has ten variables.

Exercise 2Explore

Open the table Cross-validation by fold from the Outputs. In how many of the random folds is X + SDA better than the baseline? Which spatial fold is the odd one, and why?

Answer

In four of the five random folds; in fold 4 it is slightly lower (0.335 against 0.337). Spatial fold 5 has 28 test samples, against 166 to 297 in the others, and a negative R² for both models (−0.284 and −0.239). The blocks are dealt to the folds whole, so the folds can be very unequal.

Exercise 3Interpret

A colleague writes: "SDA improves the spatial prediction of zinc by 86%." Check this against the cross-validation tables. Is the sentence justified?

Answer

No. The 86% is the change from 0.076 to 0.141 as a share of a very small baseline: the gain is 0.065 in R², and the fold SDs are 0.21 and 0.24. Report the two values with their SDs and the number of folds in which the model was better (four of five), and say that the gain lies inside the variation between folds.

Exercise 4Your data

Run SDA on your own samples and grid with the default settings (B = 80, 200 and 500 trees). Write three sentences for a results section: one on the variables selected (covariate, b, τ, sign of r), one on what they change on the prediction map, and one on the cross-validated R² of the baseline and of X + SDA in spatial folds.

Checklist

Did you give the SD over folds beside each mean R², and look at the folds table? Did you choose the block size before looking at the result, and does it leave several blocks per fold? Did you say whether an R² is the fold mean or pooled? Is the response absent from the covariates?

References

Heterra guide, for version 1.6.0. © 2026 Yongze Song. Documentation and tutorial data: CC BY 4.0.