Package 'griddy'

Title: Geospatial Distribution Dynamics for Simple Features
Description: Tools for exploratory geospatial distribution dynamics with 'sf' objects and tidy data. Provides pooled and time-specific classification of longitudinal spatial values, classic discrete Markov transition matrices, spatial Markov matrices conditioned on spatial-lag classes, endpoint and adjacent rank mobility summaries, ergodic-chain summaries, transition-regime homogeneity tests, and 'ggplot2' visualizations. Methods follow Rey (2001) <doi:10.1111/j.1538-4632.2001.tb00444.x> and Rey et al. (2016) <doi:10.1007/s10109-016-0234-x>; design is inspired by the Python 'PySAL' 'giddy' package <https://pysal.org/giddy/>.
Authors: Dmitry Shkolnik [aut, cre]
Maintainer: Dmitry Shkolnik <[email protected]>
License: MIT + file LICENSE
Version: 0.2.0
Built: 2026-10-01 07:45:42 UTC
Source: https://github.com/dshkol/griddy

Help Index


Class Intervals Used By A griddy Object

Description

Class Intervals Used By A griddy Object

Usage

class_intervals(x, ...)

Arguments

x

A griddy result object.

...

Reserved for future methods.

Value

A tibble of class intervals when available.

Examples

panel <- data.frame(id = rep(1:3, each = 2), year = rep(2020:2021, 3), value = 1:6)
classes <- classify_dynamics(panel, id, year, value, k = 3)
class_intervals(classes)

Classify Longitudinal Values For Distribution Dynamics

Description

Converts numeric values in a long panel into ordered classes suitable for transition analysis.

Usage

classify_dynamics(
  data,
  id,
  time,
  value,
  method = c("pooled_quantile", "time_quantile", "fixed", "existing"),
  k = 5,
  breaks = NULL,
  labels = NULL
)

Arguments

data

A data frame or sf object in long format.

id, time, value

Columns identifying spatial unit, time, and value.

method

Classification method. "pooled_quantile" uses one set of quantile breaks across all periods. "time_quantile" uses period-specific ranks. "fixed" uses user-supplied breaks. "existing" treats value as an already classified state.

k

Number of quantile classes.

breaks

Breaks for method = "fixed".

labels

Optional class labels.

Value

A data frame or sf object with a class column and class grd_classes.

Examples

panel <- data.frame(
  id = rep(letters[1:4], each = 3),
  year = rep(2020:2022, times = 4),
  value = c(8, 9, 11, 10, 12, 13, 15, 14, 16, 20, 22, 25)
)

classes <- classify_dynamics(panel, id, year, value, k = 3)
classes
class_intervals(classes)

Mean First-Passage Times

Description

Computes the matrix of mean first-passage times for an ergodic transition probability matrix following Kemeny and Snell: entry ⁠[i, j]⁠ is the expected number of transitions to reach class j for the first time starting from class i. Diagonal entries are mean recurrence times, the reciprocal of the stationary distribution.

Usage

first_passage(x)

Arguments

x

A grd_markov object or a square transition probability matrix. The underlying chain must be irreducible; periodic chains are supported, while matrices with absorbing or unreachable classes are rejected.

Value

A square numeric matrix of mean first-passage times.

Examples

prob <- matrix(c(0.9, 0.1, 0.2, 0.8), nrow = 2, byrow = TRUE)
first_passage(prob)

Test Homogeneity Of Transition Matrices Across Regimes

Description

Tests whether transition dynamics are homogeneous across regimes – for a spatial Markov object, whether the transition matrices conditioned on spatial-lag class genuinely differ from the pooled matrix (Rey, Kang, and Wolf 2016). Three statistics are reported: a Pearson chi-squared Q test and a likelihood-ratio test with the degrees-of-freedom adjustment of Bickenbach and Bald (2003), and the Kullback information test (Kullback, Kupperman, and Ku 1962). The Pearson and likelihood-ratio statistics mirror the PySAL giddy Spatial_Markov homogeneity attributes. The Kullback statistic uses origin-state (row) margins; this deliberately differs from giddy.markov.kullback() through giddy 2.3.9, which uses terminal-state (column) margins for the stratum-specific term.

Usage

homogeneity_test(x, ...)

Arguments

x

A grd_spatial_markov object, or a list of regime transition count matrices of identical dimensions (counts, not probabilities).

...

Reserved for future methods.

Value

A tibble with one row per test (chi2, likelihood_ratio, kullback) and columns test, statistic, df, and p_value. The null hypothesis is that all regimes share the pooled transition matrix; small p-values indicate the conditional dynamics differ.

Examples

panel <- data.frame(
  id = rep(1:9, each = 3),
  year = rep(2020:2022, times = 9),
  value = c(
    1, 2, 3, 4, 3, 5, 6, 7, 6, 8, 9, 10, 11, 10,
    12, 13, 14, 13, 15, 16, 17, 18, 17, 19, 20, 21, 20
  )
)
grid <- sf::st_sf(
  id = 1:9,
  geometry = sf::st_make_grid(
    sf::st_bbox(c(xmin = 0, ymin = 0, xmax = 3, ymax = 3)),
    n = c(3, 3)
  )
) |>
  dplyr::mutate(
    nb = sfdep::st_contiguity(geometry),
    wt = sfdep::st_weights(nb)
  )
spatial <- spatial_markov(panel, id, year, value, geometry = grid, k = 3)
homogeneity_test(spatial)

Spatial Lag Intervals Used By A Spatial Markov Object

Description

Spatial Lag Intervals Used By A Spatial Markov Object

Usage

lag_intervals(x)

Arguments

x

A grd_spatial_markov object.

Value

A tibble of spatial-lag class intervals.

Examples

panel <- data.frame(
  id = rep(1:4, each = 2),
  year = rep(2020:2021, times = 4),
  value = c(1, 2, 2, 3, 4, 3, 5, 6)
)
grid <- sf::st_sf(
  id = 1:4,
  geometry = sf::st_make_grid(
    sf::st_bbox(c(xmin = 0, ymin = 0, xmax = 2, ymax = 2)),
    n = c(2, 2)
  )
) |>
  dplyr::mutate(
    nb = sfdep::st_contiguity(geometry),
    wt = sfdep::st_weights(nb)
  )
spatial <- spatial_markov(panel, id, year, value, geometry = grid, k = 2)
lag_intervals(spatial)

Estimate Classic Markov Transition Dynamics

Description

Estimates transition counts and probabilities between adjacent periods for a classified long panel.

Usage

markov_dynamics(classes, id, time, state = class)

Arguments

classes

A classified data frame from classify_dynamics() or any data frame with ID, time, and state columns.

id, time, state

Columns identifying spatial unit, time, and state.

Value

A grd_markov object.

Examples

panel <- data.frame(
  id = rep(letters[1:4], each = 3),
  year = rep(2020:2022, times = 4),
  value = c(8, 9, 11, 10, 12, 13, 15, 14, 16, 20, 22, 25)
)

classes <- classify_dynamics(panel, id, year, value, k = 3)
markov <- markov_dynamics(classes, id, year, class)

markov
transition_matrix(markov)
steady_state(markov)

Markov Mobility Indices

Description

Computes scalar mobility indices summarising how much movement a transition probability matrix implies, following Formby, Smith, and Zheng (2004) and mirroring giddy.mobility.markov_mobility() in PySAL giddy.

Usage

mobility_index(
  x,
  measure = c("prais", "determinant", "eigen", "bartholomew1", "bartholomew2"),
  initial = NULL
)

Arguments

x

A grd_markov object or a square transition probability matrix.

measure

Character vector of indices to compute. Any of:

  • "prais": the Prais–Shorrocks trace index, (k - trace(P)) / (k - 1).

  • "determinant": ⁠1 - |det(P)|⁠.

  • "eigen": the Sommers–Conlisk index, one minus the modulus of the second-largest eigenvalue of P.

  • "bartholomew1": (k - k * sum(initial * diag(P))) / (k - 1).

  • "bartholomew2": the expected number of class boundaries crossed in one transition, ⁠sum(initial[i] * P[i, j] * |i - j|) / (k - 1)⁠. Class distance uses the class ordering, so classes are assumed ordinal.

initial

Optional initial distribution over classes used by the Bartholomew indices. Defaults to the uniform distribution, matching giddy.

Value

A named numeric vector with one element per requested measure. All indices are 0 for the identity matrix (no mobility) and increase with mobility.

Examples

prob <- matrix(c(0.9, 0.1, 0.2, 0.8), nrow = 2, byrow = TRUE)
mobility_index(prob)
mobility_index(prob, measure = "prais")

Plot Rank Mobility

Description

Plot Rank Mobility

Usage

plot_rank_mobility(x)

Arguments

x

A grd_rank_mobility object returned by rank_mobility().

Value

A ggplot object.


Plot Spatial Markov Matrices

Description

Plot Spatial Markov Matrices

Usage

plot_spatial_markov(x)

Arguments

x

A grd_spatial_markov object.

Value

A ggplot object.

Examples

panel <- data.frame(
  id = rep(1:4, each = 2),
  year = rep(2020:2021, times = 4),
  value = c(1, 2, 2, 3, 4, 3, 5, 6)
)
grid <- sf::st_sf(
  id = 1:4,
  geometry = sf::st_make_grid(
    sf::st_bbox(c(xmin = 0, ymin = 0, xmax = 2, ymax = 2)),
    n = c(2, 2)
  )
) |>
  dplyr::mutate(
    nb = sfdep::st_contiguity(geometry),
    wt = sfdep::st_weights(nb)
  )
spatial <- spatial_markov(panel, id, year, value, geometry = grid, k = 2)
plot_spatial_markov(spatial)

Plot A Transition Matrix

Description

Plot A Transition Matrix

Usage

plot_transition_matrix(x)

Arguments

x

A grd_markov object.

Value

A ggplot object.

Examples

panel <- data.frame(id = rep(1:4, each = 2), year = rep(2020:2021, 4), value = 1:8)
markov <- panel |>
  classify_dynamics(id, year, value, k = 2) |>
  markov_dynamics(id, year, class)

plot_transition_matrix(markov)

Compute Rank Mobility

Description

Computes simple rank changes for map-ready exploratory analysis.

Usage

rank_mobility(
  data,
  id,
  time,
  value,
  compare = c("endpoint", "adjacent"),
  descending = TRUE
)

Arguments

data

A long data frame or sf object.

id, time, value

Columns identifying spatial unit, time, and value.

compare

"endpoint" compares first and last observed periods per unit. "adjacent" compares adjacent periods.

descending

If TRUE, larger values receive better ranks.

Value

A grd_rank_mobility data frame or sf object.

Examples

panel <- data.frame(
  id = rep(letters[1:4], each = 3),
  year = rep(2020:2022, times = 4),
  value = c(8, 9, 11, 10, 12, 13, 15, 14, 16, 20, 22, 25)
)

rank_mobility(panel, id, year, value)

Expected Sojourn Times

Description

Computes the expected number of consecutive periods a unit remains in each class once it enters it, 1 / (1 - p_ii). Absorbing classes (p_ii = 1) have infinite sojourn times.

Usage

sojourn_time(x)

Arguments

x

A grd_markov object or a square transition probability matrix.

Value

A named numeric vector of expected sojourn times, one per class.

Examples

prob <- matrix(c(0.9, 0.1, 0.2, 0.8), nrow = 2, byrow = TRUE)
sojourn_time(prob)

Estimate Spatial Markov Transition Dynamics

Description

Estimates transition matrices conditioned on the class of each unit's spatial lag at the start of the transition period.

Usage

spatial_markov(
  data,
  id,
  time,
  value,
  geometry = NULL,
  listw = NULL,
  nb = NULL,
  k = 5,
  lag_k = k,
  class_method = c("pooled_quantile", "time_quantile", "fixed"),
  zero.policy = TRUE
)

Arguments

data

A long data frame or sf object.

id, time, value

Columns identifying spatial unit, time, and value.

geometry

An sf tibble with one row per spatial unit (a single time slice's geography), carrying nb and wt list-columns produced by sfdep::st_contiguity() and sfdep::st_weights(). The preferred input.

listw

A row-standardized spdep listw object. Accepted for compatibility with prior workflows; use geometry for new code.

nb

A spdep neighbor list, used only when both geometry and listw are NULL. Converted with spdep::nb2listw(style = "W").

k

Number of value classes.

lag_k

Number of spatial-lag classes.

class_method

Value classification method passed to classify_dynamics().

zero.policy

Passed to spdep lag/weight helpers.

Value

A grd_spatial_markov object.

Examples

panel <- data.frame(
  id = rep(1:4, each = 3),
  year = rep(2020:2022, times = 4),
  value = c(1, 2, 3, 2, 3, 4, 4, 3, 5, 5, 6, 7)
)

grid <- sf::st_sf(
  id = 1:4,
  geometry = sf::st_make_grid(
    sf::st_bbox(c(xmin = 0, ymin = 0, xmax = 2, ymax = 2)),
    n = c(2, 2)
  )
) |>
  dplyr::mutate(
    nb = sfdep::st_contiguity(geometry),
    wt = sfdep::st_weights(nb)
  )

spatial <- spatial_markov(panel, id, year, value, geometry = grid, k = 2)

spatial
lag_intervals(spatial)
transition_matrix(spatial, "count", lag_class = "Q1")

Estimate Stationary Distribution

Description

Estimate Stationary Distribution

Usage

steady_state(x)

Arguments

x

A grd_markov object or transition probability matrix.

Value

A numeric vector.

Examples

prob <- matrix(c(0.8, 0.2, 0.3, 0.7), nrow = 2, byrow = TRUE)
steady_state(prob)

Extract A Transition Matrix

Description

Extract A Transition Matrix

Usage

transition_matrix(x, type = c("probability", "count"), lag_class = NULL)

Arguments

x

A grd_markov or grd_spatial_markov object.

type

"probability" or "count".

lag_class

Optional lag class for grd_spatial_markov.

Value

A matrix.

Examples

panel <- data.frame(
  id = rep(letters[1:4], each = 3),
  year = rep(2020:2022, times = 4),
  value = c(8, 9, 11, 10, 12, 13, 15, 14, 16, 20, 22, 25)
)
markov <- panel |>
  classify_dynamics(id, year, value, k = 3) |>
  markov_dynamics(id, year, class)

transition_matrix(markov, "count")

US State Per-Capita Personal Income, 1929-2009

Description

Per-capita personal income for the 48 contiguous US states in nominal dollars. Mirrors the canonical usjoin panel used in PySAL giddy and the spatial Markov literature, so examples and validation in this package are directly comparable to that reference work.

Usage

usjoin

Format

A tibble with 3,888 rows (48 states x 81 years) and 4 columns:

name

State name.

state_fips

State FIPS code, integer.

year

Year, integer 1929 to 2009.

income

Nominal per-capita personal income, integer USD.

Source

PySAL libpysal examples/us_income/usjoin.csv. The original series is constructed from US Bureau of Economic Analysis state personal income tables. See https://github.com/pysal/libpysal.

References

Rey, S. J. (2001). Spatial empirics for economic growth and convergence. Geographical Analysis, 33(3), 195-214.

Rey, S. J., Kang, W., & Wolf, L. (2016). The properties of tests for spatial effects in discrete Markov chain models of regional income distribution dynamics. Journal of Geographical Systems, 18(4), 377-398.

Examples

data(usjoin)
head(usjoin)
range(usjoin$year)