Package {spatialRegroup}


Title: Iterative Spatial Regrouping of Administrative Units by Attributive Affinity
Version: 0.1.0
Description: Evaluates the statistical coherence of existing administrative partitions (e.g. inter-municipal groupings, districts) by identifying spatial units whose attributive profile is more similar to a neighbouring group than to their own. Border units are iteratively reassigned to the group they are most affine with, based on Euclidean or Mahalanobis distance computed on user-supplied numeric variables, with optional per-variable weighting and standardisation. Spatial contiguity is enforced throughout: isolated candidates are reintegrated into their original group, disconnected fragments are resolved, and empty groups are restored. Convergence is monitored via an eta-squared cohesion criterion. The resulting partition can be compared to the original administrative delineation using multilevel models, providing a quantitative measure of boundary inefficiency.
License: GPL-3
Depends: R (≥ 4.1.0)
Encoding: UTF-8
RoxygenNote: 7.3.1
Imports: dplyr, sf, spdep, igraph, rlang
NeedsCompilation: no
Packaged: 2026-05-06 08:49:27 UTC; User
Author: Nicolas Ausello ORCID iD [aut, cre]
Maintainer: Nicolas Ausello <nicolasausello@yahoo.fr>
Repository: CRAN
Date/Publication: 2026-05-11 19:10:09 UTC

Rattacher chaque commune candidate au groupe voisin le plus proche

Description

Rattacher chaque commune candidate au groupe voisin le plus proche

Usage

assign_best_group(
  data,
  group_var,
  vars_attr,
  profiles,
  nb = NULL,
  local_profile = TRUE,
  weights = NULL,
  standardize = TRUE
)

Arguments

data

Un objet sf avec colonne "candidate" et "id_row"

group_var

Variable de groupe

vars_attr

Variables attributaires

profiles

Profils moyens par groupe (utilises en fallback si local_profile = FALSE)

nb

Matrice de voisinage (spdep) — obligatoire si local_profile = TRUE

local_profile

Si TRUE (defaut), compare au profil des membres adjacents du groupe cible plutot qu'au centroide global du groupe. Plus representatif pour les grands groupes.

weights

Vecteur de poids pour les variables (meme longueur que vars_attr)

standardize

Standardiser les variables avant calcul (defaut TRUE)

Value

data.frame avec id_row et best_group

Examples

library(sf)
make_sq <- function(x, y) {
  st_polygon(list(matrix(
    c(x, y, x+1, y, x+1, y+1, x, y+1, x, y),
    ncol = 2, byrow = TRUE
  )))
}
toy <- st_sf(
  EPCI = c('A', 'A', 'B', 'A', 'B', 'B'),
  var1 = c(1.0, 1.2, 3.8, 1.1, 3.9, 3.7),
  var2 = c(2.0, 1.9, 6.0, 2.1, 5.8, 6.1),
  geometry = st_sfc(
    make_sq(0,0), make_sq(1,0), make_sq(2,0),
    make_sq(0,1), make_sq(1,1), make_sq(2,1)
  )
)
toy[['id_row']]    <- seq_len(nrow(toy))
toy[['candidate']] <- c(FALSE, FALSE, TRUE, FALSE, FALSE, FALSE)
nb       <- build_neighbors(toy)
profiles <- compute_profiles(toy, 'EPCI', c('var1', 'var2'))
assign_best_group(toy, 'EPCI', c('var1', 'var2'), profiles, nb = nb)

Construire la matrice de voisinage spatial

Description

Construire la matrice de voisinage spatial

Usage

build_neighbors(data, type = "queen")

Arguments

data

Un objet sf

type

"queen" ou "rook"

Value

Un objet nb (spdep)

Examples

library(sf)
make_sq <- function(x, y) {
  st_polygon(list(matrix(
    c(x, y, x+1, y, x+1, y+1, x, y+1, x, y),
    ncol = 2, byrow = TRUE
  )))
}
toy <- st_sf(
  EPCI = c('A', 'A', 'B', 'A', 'B', 'B'),
  var1 = c(1.0, 1.2, 3.8, 1.1, 3.9, 3.7),
  var2 = c(2.0, 1.9, 6.0, 2.1, 5.8, 6.1),
  geometry = st_sfc(
    make_sq(0,0), make_sq(1,0), make_sq(2,0),
    make_sq(0,1), make_sq(1,1), make_sq(2,1)
  )
)
nb <- build_neighbors(toy)
length(nb)  # 6 elements (un par commune)

Calculer les affinites attributaires des communes frontalières

Description

Calculer les affinites attributaires des communes frontalières

Usage

compute_affinity(
  data,
  nb,
  group_var,
  vars_attr,
  method = "euclidean",
  threshold = 0,
  weights = NULL,
  standardize = TRUE
)

Arguments

data

Un objet sf

nb

Matrice de voisinage (spdep)

group_var

Nom de la variable de groupe (ex: "EPCI")

vars_attr

Vecteur de noms de variables attributaires

method

Methode de distance : "euclidean" (defaut) ou "mahalanobis"

threshold

Seuil d'affinite au-dela duquel une unite est candidate (defaut 0)

weights

Vecteur de poids pour les variables (meme longueur que vars_attr, defaut NULL = poids egaux). Applique apres standardisation.

standardize

Standardiser les variables avant calcul (defaut TRUE)

Value

Un data.frame avec dist_intra, dist_extra, affinite et candidat

Examples

library(sf)
make_sq <- function(x, y) {
  st_polygon(list(matrix(
    c(x, y, x+1, y, x+1, y+1, x, y+1, x, y),
    ncol = 2, byrow = TRUE
  )))
}
toy <- st_sf(
  EPCI = c('A', 'A', 'B', 'A', 'B', 'B'),
  var1 = c(1.0, 1.2, 3.8, 1.1, 3.9, 3.7),
  var2 = c(2.0, 1.9, 6.0, 2.1, 5.8, 6.1),
  geometry = st_sfc(
    make_sq(0,0), make_sq(1,0), make_sq(2,0),
    make_sq(0,1), make_sq(1,1), make_sq(2,1)
  )
)
nb  <- build_neighbors(toy)
aff <- compute_affinity(toy, nb, group_var = 'EPCI',
                        vars_attr = c('var1', 'var2'))
aff[, c('id_row', 'affinite', 'candidat')]

Calculer la coherence interne d'un groupement (eta-carre moyen)

Description

Mesure la part de variance inter-groupe sur la variance totale pour chaque variable attributaire, puis en fait la moyenne. Valeur entre 0 et 1 : plus elle est elevee, plus le groupement est coherent avec les variables. Equivalent a un eta² (rapport de correlation) sans necessiter de modele mixte.

Usage

compute_cohesion(data, group_var, vars_attr)

Arguments

data

Un objet sf ou data.frame

group_var

Nom de la variable de groupe

vars_attr

Vecteur de noms de variables attributaires

Value

Un scalaire entre 0 et 1 (moyenne des eta² par variable)

Examples

library(sf)
make_sq <- function(x, y) {
  st_polygon(list(matrix(c(x,y,x+1,y,x+1,y+1,x,y+1,x,y),ncol=2,byrow=TRUE)))
}
toy <- st_sf(EPCI=c('A','A','B','A','B','B'),
  var1=c(1.0,1.2,3.8,1.1,3.9,3.7), var2=c(2.0,1.9,6.0,2.1,5.8,6.1),
  geometry=st_sfc(make_sq(0,0),make_sq(1,0),make_sq(2,0),
                  make_sq(0,1),make_sq(1,1),make_sq(2,1)))
compute_cohesion(toy, 'EPCI', c('var1', 'var2'))

Calculer les profils moyens par groupe

Description

Calculer les profils moyens par groupe

Usage

compute_profiles(data, group_var, vars_attr)

Arguments

data

Un objet sf

group_var

Variable de groupe

vars_attr

Variables attributaires

Value

data.frame des profils moyens par groupe

Examples

library(sf)
make_sq <- function(x, y) {
  st_polygon(list(matrix(
    c(x, y, x+1, y, x+1, y+1, x, y+1, x, y),
    ncol = 2, byrow = TRUE
  )))
}
toy <- st_sf(
  EPCI = c('A', 'A', 'B', 'A', 'B', 'B'),
  var1 = c(1.0, 1.2, 3.8, 1.1, 3.9, 3.7),
  var2 = c(2.0, 1.9, 6.0, 2.1, 5.8, 6.1),
  geometry = st_sfc(
    make_sq(0,0), make_sq(1,0), make_sq(2,0),
    make_sq(0,1), make_sq(1,1), make_sq(2,1)
  )
)
toy[['candidate']] <- FALSE
profiles <- compute_profiles(toy, 'EPCI', c('var1', 'var2'))
profiles

Reintegrer les communes candidates isolees

Description

Reintegrer les communes candidates isolees

Usage

remove_isolates(data, nb)

Arguments

data

Un objet sf avec colonne "candidate"

nb

Matrice de voisinage

Value

data avec candidats isoles remis a FALSE

Examples

library(sf)
make_sq <- function(x, y) {
  st_polygon(list(matrix(c(x,y,x+1,y,x+1,y+1,x,y+1,x,y), ncol=2, byrow=TRUE)))
}
toy <- st_sf(EPCI=c('A','A','B','A','B','B'),
  var1=c(1.0,1.2,3.8,1.1,3.9,3.7), var2=c(2.0,1.9,6.0,2.1,5.8,6.1),
  geometry=st_sfc(make_sq(0,0),make_sq(1,0),make_sq(2,0),
                  make_sq(0,1),make_sq(1,1),make_sq(2,1)))
toy[['candidate']] <- c(FALSE, TRUE, FALSE, FALSE, FALSE, FALSE)
nb  <- build_neighbors(toy)
res <- remove_isolates(toy, nb)
res[['candidate']]

Regroupement spatial iteratif par affinite attributaire

Description

Regroupement spatial iteratif par affinite attributaire

Usage

spatialRegroup(
  data,
  group_var,
  vars_attr,
  method = "euclidean",
  threshold = 0,
  iterations = 1,
  min_group = 1,
  nb_type = "queen",
  remove_isolates = TRUE,
  weights = NULL,
  standardize = TRUE,
  local_profile = TRUE,
  cohesion_tol = 0.001,
  verbose = TRUE
)

Arguments

data

sf object

group_var

Variable de groupe initial (ex: "EPCI")

vars_attr

Variables attributaires pour le calcul d'affinite

method

Methode de distance : "euclidean" (defaut) ou "mahalanobis"

threshold

Seuil d'affinite pour identifier un candidat (defaut 0)

iterations

Nombre maximum d'iterations (defaut 1)

min_group

Taille minimale d'un groupe valide pour le rattachement (defaut 1)

nb_type

Type de voisinage spatial : "queen" (defaut) ou "rook"

remove_isolates

Reintegrer les candidats isoles (defaut TRUE)

weights

Vecteur de poids pour les variables attributaires (meme longueur que vars_attr, defaut NULL = poids egaux). Applique apres standardisation. Exemple : c(0.5, 0.3, 0.2) pour donner plus de poids au prix.

standardize

Standardiser les variables avant calcul de distance (defaut TRUE). Recommande pour que les variables soient comparables entre elles.

local_profile

Si TRUE (defaut), compare chaque candidat au profil des membres adjacents du groupe cible plutot qu'au centroide global du groupe. Plus representatif pour les grands groupes heterogenes.

cohesion_tol

Seuil minimal de progression de la coherence (eta²) entre deux iterations. L'algorithme s'arrete si la progression est inferieure a ce seuil (defaut 0.001). Mettre a NULL pour desactiver ce critere d'arret.

verbose

Afficher les messages de progression (defaut TRUE)

Value

Un sf object identique a l'entree avec les colonnes supplementaires : {group_var}_regroup (affectation finale) et candidate (TRUE si l'unite a ete reclassee).

Examples

library(sf)

# Helper : cree un carre unitaire de coin inferieur gauche (x, y)
make_sq <- function(x, y) {
  st_polygon(list(matrix(
    c(x, y, x+1, y, x+1, y+1, x, y+1, x, y),
    ncol = 2, byrow = TRUE
  )))
}

# Grille 3x2 : 6 communes, 2 groupes (A et B)
toy <- st_sf(
  EPCI  = c('A', 'A', 'B', 'A', 'B', 'B'),
  var1  = c(1.0, 1.2, 3.8, 1.1, 3.9, 3.7),
  var2  = c(2.0, 1.9, 6.0, 2.1, 5.8, 6.1),
  geometry = st_sfc(
    make_sq(0,0), make_sq(1,0), make_sq(2,0),
    make_sq(0,1), make_sq(1,1), make_sq(2,1)
  )
)

res <- spatialRegroup(
  data      = toy,
  group_var = 'EPCI',
  vars_attr = c('var1', 'var2'),
  verbose   = FALSE
)
res[, c('EPCI', 'EPCI_regroup', 'candidate')]