`prepare_spatialrisk()`, `select_candidates()`, and `optimize_hotspot()`
expose the main steps used by concentration_hotspot. They are useful
when the intermediate search state needs to be inspected or when the same
prepared portfolio is used in more than one hotspot search strategy.
prepare_spatialrisk(
data,
value,
radius = 200,
cell_size = 100,
lon = "lon",
lat = "lat",
crs_metric = 3035
)select_candidates(
x,
grid_spacing = 1,
max_refinement_points = 1500,
method = c("continuous", "observed", "grid"),
threshold = NULL,
progress = TRUE,
grid_precision = lifecycle::deprecated()
)
optimize_hotspot(
x,
n_hotspots = 1,
progress = TRUE,
top_n = lifecycle::deprecated()
)
# S3 method for spatialrisk_hotspot_workflow
plot(x, type = c("auto", "raster", "candidates"), ...)
`prepare_spatialrisk()` and `select_candidates()` return an object of class
`spatialrisk_hotspot_workflow`. `optimize_hotspot()` returns the same
`hotspot` object structure as concentration_hotspot.
A data.frame containing point-level exposures. Must include longitude and latitude in EPSG:4326 and the value of interest. Coordinates are projected internally to `crs_metric`.
A string giving the numeric column in `data` to aggregate within each radius.
Numeric. Radius of the circle in meters.
Numeric. Size of the raster cells used for the initial screening raster.
A string giving the longitude column in `data`.
A string giving the latitude column in `data`.
Numeric. EPSG code for a projected CRS with meter units. The default `3035` is ETRS89 / LAEA Europe.
A prepared spatial-risk workflow object returned by `prepare_spatialrisk()` or `select_candidates()`.
Numeric. Spacing between candidate grid centres in the units of `crs_metric`; for the default metric CRS these units are meters. Used for grid-based refinement.
Positive integer. Maximum number of local points used for pair-intersection refinement before falling back to grid refinement in a search state produced by `select_candidates()`. Direct optimisation of a prepared object never falls back to a grid; values above this limit produce a computational-cost warning instead.
Hotspot search strategy. `"continuous"` is the default and searches for centres that may lie between observed points. `"observed"` searches only observed point locations. `"grid"` uses the grid-refinement workflow.
Optional numeric lower bound for candidate focal cells. If `NULL`, the lower bound is estimated using the same preliminary refinement step as `concentration_hotspot()`.
Logical. Whether to print progress messages.
Deprecated. Use `grid_spacing` instead.
Positive integer. Number of non-overlapping hotspots to return.
Deprecated. Use `n_hotspots` instead.
Plot type. `"auto"` shows the prepared raster before candidate selection and selected focal candidate cells afterwards.
Additional arguments passed to `mapview::mapview()`.
Martin Haringa
The three-step interface decomposes the hotspot workflow without replacing `concentration_hotspot()`. The wrapper remains the simplest public function for normal use, while the decomposed functions make the intermediate candidate selection visible.
`optimize_hotspot()` optimises over the candidate search state supplied to it. Called directly on the output of `prepare_spatialrisk()`, it performs a full geometric search: candidate centres are the active observed locations and the valid radius-circle intersections generated by every active point pair no farther than twice the radius apart. This route does not use raster screening or grid fallback and is intended mainly for small portfolios, diagnostics, validation, and methodological benchmarks. Pair generation can be computationally expensive.
In `select_candidates()`, `threshold = NULL` estimates a lower bound by taking the highest focal raster cells, refining those cells on a small local grid, evaluating those centres in the projected metric coordinates, and using the best feasible value as the candidate-cell threshold. The focal cells first survive when their moving-window sum is at least this lower bound. For continuous search with non-negative values and an automatic threshold, a second bound sums only active points whose minimum distance to the closed centre-cell rectangle is within the radius, allowing for the scoring tolerance. It does not count the entire value of an extra raster cell. The five highest surviving point bounds also seed feasible trial centres; only their actual portfolio sums can raise the lower bound. Cells with a point bound strictly below that lower bound are removed. The focal window includes the requested radius plus a raster-cell diagonal. With non-negative values, its sum is therefore an upper bound for every exact centre located in that focal cell. Under the default automatic threshold, observed and pair-intersection centres are mapped back to the raster and exact evaluation is restricted to centres that lie in a selected cell. For a point pair, its two possible circle centres are screened separately. For a single hotspot, a streaming Rcpp angular sweep maintains the complete active-portfolio total at the retained pair-intersection events; this avoids materialising and separately querying every centre. With complete pair-intersection refinement and exact scoring, and provided no grid fallback occurs, this removes no cell that can contain a strictly improving centre and therefore preserves a global optimum of the single-disk problem. The guarantee does not apply to a user-supplied threshold, negative values, or grid fallback.
Candidate screening never defines the evaluation portfolio. Every retained centre is scored against all records in the complete active portfolio, so a point outside the candidate-generation subset still contributes when it lies within the radius. Point-to-raster-cell membership is stored during preparation and reused to retrieve nearby records; candidate regions within one hotspot iteration share the same active-portfolio evaluation state. When `optimize_hotspot(n_hotspots > 1)` or `concentration_hotspot(n_hotspots > 1)` is used, the points in the selected hotspot are removed and the candidate-selection logic is run again for the next hotspot. Therefore the number of candidate cells shown by `select_candidates()` for the first iteration does not limit the number of hotspots returned by `n_hotspots`.
portfolio <- Groningen[1:200, c("lon", "lat", "amount")]
model <- prepare_spatialrisk(portfolio, value = "amount", radius = 200,
cell_size = 100)
# Full geometric reference search
full <- optimize_hotspot(model, progress = FALSE)
# Screened continuous search
screened <- model |>
select_candidates(progress = FALSE) |>
optimize_hotspot(progress = FALSE)
full$hotspots
screened$hotspots
Run the code above in your browser using DataLab