Learn R Programming

spatialrisk (version 0.8.2)

concentration_hotspot: Find fixed-radius concentration hotspots

Description

Finds fixed-radius concentration hotspots in weighted point-level data. This is a computational building block for weighted circle-placement problems: given point locations and a fixed radius, find a centre whose surrounding circle contains a large aggregated value. In insurance applications, the weights may represent insured values or another exposure measure. This function is a wrapper around the decomposed workflow prepare_spatialrisk, select_candidates, and optimize_hotspot.

Usage

concentration_hotspot(
  data,
  value,
  n_hotspots = 1,
  radius = 200,
  cell_size = 100,
  grid_spacing = 1,
  max_refinement_points = 1500,
  lon = "lon",
  lat = "lat",
  crs_metric = 3035,
  progress = TRUE,
  method = c("continuous", "observed", "grid"),
  top_n = lifecycle::deprecated(),
  grid_precision = lifecycle::deprecated()
)

Value

An object of class hotspot. The main components are

hotspots, containing the selected centre coordinates and summed values, and contributing_points, containing the points inside the selected hotspot radii. The summed value column is named from value; for example, value = "amount" creates an amount_sum column. In contributing_points, data_row gives the row number of the contributing point in the original input data.

Arguments

data

A data.frame containing point-level exposures. Must include columns for longitude and latitude in EPSG:4326 and the value of interest. The coordinates are projected internally to `crs_metric`.

value

A string giving the name of the numeric column in data to aggregate within each radius.

n_hotspots

Positive integer greater or equal to 1. Number of sequential non-overlapping hotspots to return. Default is 1.

radius

Numeric. Radius of the circle in meters. This is typically the application-specific radius of interest. Default is 200.

cell_size

Numeric. Size of the initial screening cells in meters. This is used by method = "continuous" and method = "grid". Smaller values give a finer initial search but increase computation time. method = "observed" searches observed point locations and does not use this value as a search-grid resolution. Default is 100.

grid_spacing

Numeric. Spacing between candidate grid centres in the units of crs_metric; for the default metric CRS these units are meters. This is used by method = "grid" and by method = "continuous" only when the local subset is larger than max_refinement_points and the method falls back to grid refinement. It is not used by method = "observed". Smaller values evaluate more candidate centres and increase computation time. Default is 1.

max_refinement_points

Positive integer. Maximum number of local points used for pair-intersection refinement. If the local subset contains more points, method = "continuous" automatically falls back to the grid refinement used by method = "grid". Default is 1500.

lon

A string giving the longitude column in data. Default is "lon".

lat

A string giving the latitude column in data. Default is "lat".

crs_metric

Numeric. EPSG code for a projected CRS with meter units, used for distances, buffers, raster cells, and pair-intersection calculations. The default 3035 is ETRS89 / LAEA Europe and is a suitable default for Europe-wide applications. For other regions, choose a metric CRS appropriate to the study area, for example a local UTM zone, 5070 for the conterminous United States, or 3577 for Australia. For Asian portfolios there is no single universal choice; use a national projected CRS or the relevant UTM zone. Default is 3035.

progress

Logical. Whether to print progress messages for the main hotspot search steps. This is useful for larger portfolios and for n_hotspots > 1. Default is TRUE.

method

Hotspot search strategy. "continuous" is the default and searches for a centre that may lie between observed points. "observed" searches only observed point locations as candidate centres. "grid" uses the original grid-refinement workflow.

top_n

Deprecated. Use n_hotspots instead.

grid_precision

Deprecated. Use grid_spacing instead.

Author

Martin Haringa

Details

The default method = "continuous" first uses terra rasterisation and focal sums to identify candidate areas above an automatically estimated lower bound. It then refines all retained areas using observed local points and the circle centres implied by local point pairs. Local refinement subsets are retrieved from the raster cells that can affect each candidate area, using a conservative margin based on radius and cell_size. If more than max_refinement_points local points are involved, it falls back to the grid refinement used by method = "grid". In that fallback case, grid_spacing controls the local refinement grid; otherwise the pair-intersection step does not use grid_spacing. The focal window includes the radius plus a raster-cell diagonal. For non-negative values this makes the focal sum an upper bound for exact centres in that cell. A second screening bound sums only active points within the radius of the centre-cell rectangle, including numerical boundary tolerance. Feasible trial centres in the most promising surviving cells can improve the lower bound before further pruning. With the default automatic lower bound, exact evaluation is consequently restricted to observed or pair-intersection centres whose own raster cell passed screening; the two centres generated by a point pair are tested separately. For a single hotspot, Rcpp processes these centres as a streaming angular sweep and maintains their exact totals over the complete active portfolio. It therefore avoids materialising all centres or running a separate radius query for each one. A retained centre is never scored only against the points used to generate it. This centre-level pruning is disabled for a user-supplied threshold or negative values. Under non-negative weights, the default automatic threshold, complete pair-intersection refinement, and exact scoring with no grid fallback, this screening is optimality-preserving for the single-disk problem: a cell containing a strictly improving centre cannot be removed. The "observed" method is fast and deterministic, but can miss a larger hotspot when the optimal centre lies between observed points. The "grid" method uses a grid-based search with local refinement; smaller grid_spacing values generally increase search resolution and computation time. Use prepare_spatialrisk, select_candidates, and optimize_hotspot when these steps need to be run or inspected separately. The high-level function always uses the screened continuous search.

The underlying continuous hotspot problem can be viewed as a fixed-radius weighted circle placement problem. For point observations with non-negative values in a projected metric coordinate system, candidate centres formed by observed point locations and by intersections of radius-`r` circles around pairs of observations are sufficient to characterise the single-disk optimum. The practical method = "continuous" implementation retains that optimum under the screening conditions stated above. This guarantee does not apply to grid fallback, a user-supplied threshold, negative values, or joint optimisation of multiple circles.

Calling optimize_hotspot() directly on an object returned by prepare_spatialrisk() instead performs the complete geometric candidate search over the full active portfolio. Calling it after select_candidates() restricts candidate generation to the screened search state. In both routes, every retained centre is scored against the complete active portfolio. The direct full route does not use grid fallback and is principally intended for small validation or benchmark problems.

For n_hotspots > 1, hotspots are selected greedily: after each hotspot is found, the covered observations are removed before the next hotspot is computed. The resulting sequence is not necessarily globally optimal as a joint multi-circle problem.

References

Chazelle, B. M. and Lee, D. T. (1986). On a circle placement problem. Computing, 36(1--2), 1--16. tools:::Rd_expr_doi("10.1007/BF02238188").

Examples

Run this code
portfolio <- Groningen[1:200, c("lon", "lat", "amount")]

hotspot <- concentration_hotspot(
  portfolio,
  value = "amount",
  radius = 200,
  n_hotspots = 2,
  cell_size = 100,
  progress = FALSE
)

hotspot$hotspots
head(hotspot$contributing_points)

observed_hotspot <- concentration_hotspot(
  portfolio,
  value = "amount",
  radius = 200,
  method = "observed",
  progress = FALSE
)

rbind(
  continuous = hotspot$hotspots[1, ],
  observed = observed_hotspot$hotspots
)

Run the code above in your browser using DataLab