| Title: | Create Persistent Identifiers for Longitudinal Spatial Data |
|---|---|
| Description: | Creates dataset-local persistent identifiers for polygon units observed across time. Configurable overlap metrics, thresholds, and one-to-one matching rules identify continuity while separate identifiers track boundary versions and broader lineages through splits, mergers, and replacements. Candidate-link diagnostics, validation checks, registry reconciliation, and lineage summaries keep the resulting decisions inspectable and reproducible. |
| Authors: | Emre Cebeci [aut, cre] |
| Maintainer: | Emre Cebeci <[email protected]> |
| License: | MIT + file LICENSE |
| Version: | 0.1.0 |
| Built: | 2026-09-26 23:27:48 UTC |
| Source: | https://github.com/emre-cebeci/spatpersist |
Generates synthetic polygon data showing common spatial continuity problems: stable units, boundary changes, renames, and splits.
example_units()example_units()
An sf object containing synthetic polygons.
data <- example_units() plot(data["name"])data <- example_units() plot(data["name"])
Creates one row per spatial_id with its lineage, parent, observed time
span, number of observations and geometry versions, registry recovery count,
ambiguity count, and minimum non-missing match confidence.
id_lineages(data, time)id_lineages(data, time)
data |
A result returned by |
time |
A single character string naming the time column in |
A data frame with one row per persistent spatial identity.
result <- persist_ids(example_units(), time = "year") id_lineages(result, time = "year")result <- persist_ids(example_units(), time = "year") id_lineages(result, time = "year")
Retrieves the candidate-link diagnostics created by
persist_ids(). The table contains every positive-area overlap
considered across successive observed periods, including its overlap
statistics, mutual-best and ambiguity flags, candidate status, selection,
and confidence.
id_transitions(x)id_transitions(x)
x |
An |
A data frame of transition diagnostics.
result <- persist_ids(example_units(), time = "year") id_transitions(result)result <- persist_ids(example_units(), time = "year") id_transitions(result)
Assigns persistent identifiers by comparing polygons in each pair of
successive observed time periods. A polygon continues an earlier identity
when its selected overlap statistic meets threshold. Candidate links are
selected one-to-one, so a persistent identifier cannot occur more than once
in the same time period.
persist_ids( data, time, threshold = 0.75, metric = c("share_old", "share_new", "iou"), match_rule = c("greedy", "mutual_best"), ambiguity_tolerance = 0.05, ambiguity_action = c("flag", "new", "error"), event_threshold = 0.1, lineage_threshold = 0.6, version_threshold = 1, geometry_action = c("error", "repair"), geometry_precision = NULL, max_time_gap = Inf, registry = NULL, registry_threshold = 0.999999 )persist_ids( data, time, threshold = 0.75, metric = c("share_old", "share_new", "iou"), match_rule = c("greedy", "mutual_best"), ambiguity_tolerance = 0.05, ambiguity_action = c("flag", "new", "error"), event_threshold = 0.1, lineage_threshold = 0.6, version_threshold = 1, geometry_action = c("error", "repair"), geometry_precision = NULL, max_time_gap = Inf, registry = NULL, registry_threshold = 0.999999 )
data |
An |
time |
A single character string naming the time column in |
threshold |
A number from 0 to 1 giving the minimum overlap required for continuity. |
metric |
The overlap statistic used for matching: |
match_rule |
Candidate selection rule: |
ambiguity_tolerance |
Maximum difference between eligible top scores that is treated as a near tie. |
ambiguity_action |
How near ties should be handled: |
event_threshold |
A number from 0 to 1 giving the minimum share of a predecessor or successor used when detecting splits and mergers. |
lineage_threshold |
A number from 0 to 1 giving the minimum share of the smaller polygon that must overlap to connect two observations in the same lineage. Accepted identity matches are always connected. |
version_threshold |
A number from 0 to 1 giving the minimum IoU needed for a continuing identity to retain its current geometry version. The default of 1 creates a new version for any boundary change. |
geometry_action |
How invalid polygon geometries should be handled:
|
geometry_precision |
Optional positive precision scale passed to
|
max_time_gap |
Maximum gap across which identities may continue.
Defaults to |
registry |
Optional prior |
registry_threshold |
Minimum same-time IoU required to recover an
observation from |
Names and other non-spatial attributes are not used for matching. Unmatched polygons receive new identifiers. Strong spatial links connect related identities in a shared lineage and are used to describe splits, mergers, replacements, and complex reorganizations.
Candidate-link diagnostics are stored with the result and can be retrieved
with id_transitions().
Identifiers are dataset-local. Values such as SID000001 and LID000001
are persistent only within one dataset and its registry chain; they are not
globally unique across independent projects. Exact same-period coextensive
geometries are rejected because geometry-only matching cannot distinguish
their identities reproducibly.
The input sf object with identifier and transition columns,
including spatial_id, spatial_version_id, lineage_id, parent_id,
transition_type, match_score, match_confidence, and
match_ambiguous. registry_matched indicates recovered observations.
data <- example_units() result <- persist_ids(data, time = "year", threshold = 0.75) result[, c("year", "name", "spatial_id")]data <- example_units() result <- persist_ids(data, time = "year", threshold = 0.75) result[, c("year", "name", "spatial_id")]
Draws observations on a time-by-identity layout. Solid links are selected identity continuations; dashed links are additional spatial lineage relationships such as split and merger branches.
plot_lineage( data, time, lineage_id = NULL, show_legend = TRUE, node_cex = 1.2, ... )plot_lineage( data, time, lineage_id = NULL, show_legend = TRUE, node_cex = 1.2, ... )
data |
A result returned by |
time |
A single character string naming the time column in |
lineage_id |
Optional character vector of lineage IDs to display.
|
show_legend |
Logical; display a transition-type legend. |
node_cex |
Numeric node size. |
... |
Additional arguments passed to |
Invisibly, a list containing the plotted nodes and edges data.
result <- persist_ids(example_units(), time = "year") plot_lineage(result, time = "year", lineage_id = "LID000004")result <- persist_ids(example_units(), time = "year") plot_lineage(result, time = "year", lineage_id = "LID000004")
Checks a result for structural inconsistencies, including missing output values, duplicate identities within a time period, identities assigned to multiple lineages, invalid geometry-version sequences, invalid transition labels, invalid match scores, and broken parent or continuation links.
validate_ids(data, time)validate_ids(data, time)
data |
A data frame or |
time |
A single character string naming the time column in |
A data frame describing validation issues. A result with zero rows passed all implemented checks.
result <- persist_ids(example_units(), time = "year") validate_ids(result, time = "year")result <- persist_ids(example_units(), time = "year") validate_ids(result, time = "year")