Jointures et opérations spatiales
Appliquez st_join(), st_intersection(), st_buffer() et st_distance().
Jointures et opérations spatiales est une leçon R Academy gratuite sur CoddyKit. Ceci est la leçon 3 sur 4. Tu peux lire la leçon complète ci-dessous gratuitement — puis la pratiquer en direct dans le navigateur avec un éditeur de code intégré et un tuteur IA 24/7. Elle fait partie du parcours d'apprentissage R Academy, et ta progression se synchronise sur le web et l'application CoddyKit. Le cours R Academy comprend 4 leçons au total.
Jointures spatiales avec st_join
st_join(x, y) effectue une jointure spatiale à gauche : pour chaque entité de x, la fonction recherche dans y les entités qui satisfont un prédicat spatial (par défaut : st_intersects) et ajoute leurs attributs. Plusieurs correspondances produisent plusieurs lignes.
library(sf)
nc <- st_transform(
read_sf(system.file('shape/nc.shp', package = 'sf')), 4326
)
# Create random points within NC bounding box
set.seed(42)
bbox <- st_bbox(nc)
pts <- data.frame(
lon = runif(20, bbox['xmin'], bbox['xmax']),
lat = runif(20, bbox['ymin'], bbox['ymax'])
)
pts_sf <- st_as_sf(pts, coords = c('lon', 'lat'), crs = 4326)
# Spatial join: assign county attributes to each point
pts_with_county <- st_join(pts_sf, nc['NAME'])
cat('Points with county:\n')
print(head(pts_with_county[, c('NAME', 'geometry')], 5))st_within : point dans un polygone
st_within(x, y) renvoie une matrice creuse de valeurs logiques indiquant si chaque entité de x est entièrement incluse dans une entité de y. Cette fonction est plus stricte que st_intersects : les contacts avec la limite ne sont pas comptabilisés.
library(sf)
nc <- st_transform(
read_sf(system.file('shape/nc.shp', package = 'sf')), 4326
)
# Random points
set.seed(7)
bbox <- st_bbox(nc)
pts_sf <- st_as_sf(
data.frame(
lon = runif(30, bbox['xmin'], bbox['xmax']),
lat = runif(30, bbox['ymin'], bbox['ymax'])
),
coords = c('lon', 'lat'), crs = 4326
)
# Which points are within NC at all?
within_nc <- st_within(pts_sf, st_union(nc), sparse = FALSE)[, 1]
cat('Points within NC:', sum(within_nc), '/ 30\n')
# Keep only points inside NC
pts_inside <- pts_sf[within_nc, ]
cat('Kept:', nrow(pts_inside), 'points\n')st_intersects : test de chevauchement
st_intersects(x, y) renvoie TRUE lorsque les entités partagent une partie quelconque de leur géométrie — limite ou intérieur. Il s’agit du prédicat topologique le plus permissif. Fournissez sparse = FALSE pour obtenir une matrice logique plutôt qu’une liste de vecteurs d’indices.
library(sf)
# Create two overlapping polygons
poly1 <- st_polygon(list(matrix(c(0,0, 2,0, 2,2, 0,2, 0,0), ncol=2, byrow=TRUE)))
poly2 <- st_polygon(list(matrix(c(1,1, 3,1, 3,3, 1,3, 1,1), ncol=2, byrow=TRUE)))
poly3 <- st_polygon(list(matrix(c(5,5, 6,5, 6,6, 5,6, 5,5), ncol=2, byrow=TRUE)))
sfc <- st_sfc(poly1, poly2, poly3, crs = 32119)
# Intersects matrix
mat <- st_intersects(sfc, sparse = FALSE)
cat('Intersects matrix:\n')
print(mat)
cat('\npoly1 intersects poly2:', mat[1, 2], '\n')
cat('poly1 intersects poly3:', mat[1, 3], '\n')st_buffer : créer des zones tampons
st_buffer(sf_obj, dist) crée un polygone tampon autour de chaque entité, à la distance indiquée. Dans un CRS géographique, la distance est exprimée en degrés ; dans un CRS projeté, elle est exprimée en mètres. Reprojetez toujours les données avant de créer des zones tampons pour obtenir des résultats précis.
library(sf)
# City points in WGS84
cities <- data.frame(
city = c('Raleigh', 'Charlotte', 'Greensboro'),
lon = c(-78.639, -80.843, -79.792),
lat = c(35.779, 35.227, 36.073)
)
cities_sf <- st_as_sf(cities, coords = c('lon', 'lat'), crs = 4326)
# Project to metres for accurate buffering (NC State Plane)
cities_proj <- st_transform(cities_sf, 32119)
# 25 km buffer around each city
buffers <- st_buffer(cities_proj, dist = 25000)
cat('Buffer geometry type:', unique(as.character(st_geometry_type(buffers))), '\n')
cat('Buffer area (km2):', round(as.numeric(st_area(buffers[1, ])) / 1e6, 2), '\n')
cat('Expected (pi*25^2):', round(pi * 25^2, 2), 'km2\n')st_area : surfaces des polygones
st_area(sf_obj) calcule la surface de chaque polygone. Dans un CRS géographique, la fonction renvoie des valeurs en stéradians (peu utiles) ; dans un CRS projeté utilisant les mètres, elle renvoie des mètres carrés. Les résultats conservent leurs unités grâce au package units.
library(sf)
library(units)
nc <- read_sf(system.file('shape/nc.shp', package = 'sf'))
nc_proj <- st_transform(nc, 32119) # NC State Plane, metres
# Area in m2 with units
nc_proj$area_m2 <- st_area(nc_proj)
# Convert to km2
nc_proj$area_km2 <- set_units(nc_proj$area_m2, 'km^2')
# Summary statistics
cat('Smallest county:', nc_proj$NAME[which.min(nc_proj$area_km2)],
round(min(as.numeric(nc_proj$area_km2)), 1), 'km2\n')
cat('Largest county: ', nc_proj$NAME[which.max(nc_proj$area_km2)],
round(max(as.numeric(nc_proj$area_km2)), 1), 'km2\n')st_distance : distances par paires
st_distance(x, y) calcule une matrice des distances entre toutes les entités de x et toutes celles de y. Avec WGS84, la fonction utilise des distances géodésiques ; avec un CRS projeté, elle utilise des distances euclidiennes. Les résultats conservent leurs métadonnées units.
library(sf)
cities <- data.frame(
city = c('Raleigh', 'Charlotte', 'Greensboro', 'Wilmington'),
lon = c(-78.639, -80.843, -79.792, -77.909),
lat = c(35.779, 35.227, 36.073, 34.226)
)
cities_sf <- st_as_sf(cities, coords = c('lon', 'lat'), crs = 4326)
# Geodesic distance matrix (metres)
dist_m <- st_distance(cities_sf)
dist_km <- round(dist_m / 1000)
rownames(dist_km) <- cities$city
colnames(dist_km) <- cities$city
cat('Distance matrix (km):\n')
print(dist_km)
# Nearest neighbour for Raleigh
raleigh_dist <- as.numeric(dist_km['Raleigh', -1])
cat('\nNearest to Raleigh:',
cities$city[-1][which.min(raleigh_dist)],
min(raleigh_dist), 'km\n')st_union : dissoudre les géométries
st_union(sf_obj) fusionne toutes les entités en une seule géométrie, en supprimant les limites intérieures. Cette fonction est utile pour créer le contour unique à partir de plusieurs polygones de comtés ou pour fusionner un ensemble de zones tampons.
library(sf)
nc <- st_transform(
read_sf(system.file('shape/nc.shp', package = 'sf')), 32119
)
# Dissolve all counties into the NC state outline
nc_state <- st_union(nc)
cat('Counties before union:', nrow(nc), '\n')
cat('Features after union:', length(nc_state), '(single geometry)\n')
cat('Geometry type:', as.character(st_geometry_type(nc_state)), '\n')
# Area check: sum of counties == state area
county_area_sum <- sum(as.numeric(st_area(nc)))
state_area <- as.numeric(st_area(nc_state))
cat('Sum of county areas:', round(county_area_sum / 1e9, 2), 'km2\n')
cat('State area: ', round(state_area / 1e9, 2), 'km2\n')st_intersection : découper
st_intersection(x, y) renvoie l’intersection géométrique de chaque paire d’entités, c’est-à-dire la zone commune aux deux géométries. Cette fonction sert à découper une couche selon l’étendue d’une autre.
library(sf)
nc <- st_transform(
read_sf(system.file('shape/nc.shp', package = 'sf')), 4326
)
# Clip NC counties to a bounding rectangle (eastern NC)
clip_box <- st_as_sfc(st_bbox(c(
xmin = -78, xmax = -75,
ymin = 33.5, ymax = 36.5
), crs = 4326))
eastern_nc <- st_intersection(nc, clip_box)
cat('Original features:', nrow(nc), '\n')
cat('Clipped features: ', nrow(eastern_nc), '\n')
cat('Geometry types: ', paste(unique(as.character(st_geometry_type(eastern_nc))), collapse = ', '), '\n')Agrégation spatiale avec dplyr
Combinez st_join() avec dplyr::group_by() et summarise() pour agréger des données ponctuelles par polygone. La colonne de géométrie est automatiquement résumée (par défaut, par union) lors du regroupement d’un objet sf.
library(sf)
library(dplyr)
nc <- st_transform(
read_sf(system.file('shape/nc.shp', package = 'sf')), 4326
)
# Generate random sales events in NC
set.seed(99)
bbox <- st_bbox(nc)
pts <- st_as_sf(
data.frame(
lon = runif(200, bbox['xmin'], bbox['xmax']),
lat = runif(200, bbox['ymin'], bbox['ymax']),
sales = runif(200, 100, 1000)
),
coords = c('lon', 'lat'), crs = 4326
)
# Join then aggregate
result <- st_join(pts, nc['NAME']) |>
filter(!is.na(NAME)) |>
st_drop_geometry() |>
group_by(NAME) |>
summarise(total_sales = sum(sales), n_events = n()) |>
arrange(desc(total_sales))
cat('Top 5 counties by sales:\n')
print(head(result, 5))st_nearest_feature
st_nearest_feature(x, y) renvoie, pour chaque entité de x, l’indice de l’entité la plus proche dans y. Combinée à st_distance(), cette fonction fournit à la fois le voisin le plus proche et sa distance — ce qui est utile pour les problèmes d’affectation.
library(sf)
# Hospitals (facilities)
hospitals <- data.frame(
name = c('Hospital A', 'Hospital B', 'Hospital C'),
lon = c(-79.5, -80.2, -78.8),
lat = c(35.8, 35.3, 36.1)
)
hosp_sf <- st_as_sf(hospitals, coords = c('lon', 'lat'), crs = 4326)
# Patient locations
patients <- data.frame(
id = 1:5,
lon = c(-79.9, -80.5, -79.0, -78.5, -80.1),
lat = c(35.7, 35.2, 35.9, 35.5, 36.0)
)
pt_sf <- st_as_sf(patients, coords = c('lon', 'lat'), crs = 4326)
# Find nearest hospital for each patient
nearest_idx <- st_nearest_feature(pt_sf, hosp_sf)
pt_sf$nearest_hospital <- hospitals$name[nearest_idx]
print(st_drop_geometry(pt_sf))Flux de travail pratique : zone tampon et comptage
Schéma courant dans les situations réelles : créer une zone tampon autour d’un ensemble d’entités (par ex. des écoles), puis compter le nombre de points d’intérêt (par ex. des arrêts de bus) qui se trouvent dans chaque zone tampon à l’aide de st_join() et dplyr::count().
library(sf)
library(dplyr)
# Schools as points
schools <- data.frame(
id = 1:3,
lon = c(-79.8, -80.2, -79.4),
lat = c(35.9, 35.5, 36.1)
)
schools_sf <- st_as_sf(schools, coords = c('lon', 'lat'), crs = 4326) |>
st_transform(32119) # project to metres
# Random bus stops
set.seed(5)
stops <- data.frame(
stop_id = 1:50,
lon = rnorm(50, -79.8, 0.3),
lat = rnorm(50, 35.8, 0.2)
) |>
st_as_sf(coords = c('lon', 'lat'), crs = 4326) |>
st_transform(32119)
# 2 km buffer around each school
buffers <- st_buffer(schools_sf, dist = 2000)
buffers$school_id <- schools$id
# Count bus stops within each school buffer
joined <- st_join(stops, buffers['school_id'])
counts <- count(st_drop_geometry(joined), school_id)
cat('Bus stops within 2km:\n')
print(counts)Vérification rapide
Vous souhaitez trouver toutes les entités polygonales de la couche B qui chevauchent chaque polygone de la couche A, puis ajouter les attributs de B à A. Quelle fonction devez-vous utiliser ?
Récapitulatif : jointures et opérations spatiales
Points essentiels :
st_join(x, y)— jointure spatiale à gauche utilisant un prédicat (par défaut :st_intersects)st_within()— TRUE lorsque x est entièrement inclus dans y (limite exclue)st_intersects()— TRUE lorsqu’une partie quelconque de x touche y (le plus permissif)st_buffer(sf_obj, dist)— crée des zones tampons ; utilisez un CRS projeté pour obtenir des distances précises en mètresst_area()/st_distance()— calcule les surfaces et les distances (reprojetez d’abord pour obtenir des résultats précis)st_union()— dissout toutes les entités ;st_intersection()— découpe une couche selon une autrest_nearest_feature(x, y)— recherche du voisin le plus proche
library(sf)
nc <- st_transform(
read_sf(system.file('shape/nc.shp', package = 'sf')), 32119
)
# Quick operations summary
cat('Largest county:', nc$NAME[which.max(st_area(nc))], '\n')
nc_outline <- st_union(nc)
cat('State area km2:', round(as.numeric(st_area(nc_outline)) / 1e6, 0), '\n')Apprends R avec un tuteur IA — gratuit
Écris et exécute du vrai code dans ton navigateur, obtiens de l'aide instantanée d'un tuteur IA disponible 24h/24, et reprends là où tu t'es arrêté sur le web ou dans l'app.
- Cours
- 43
- Leçons
- 159
Questions Fréquemment Posées
La leçon « Jointures et opérations spatiales » est-elle gratuite ?
Oui — le texte complet de « Jointures et opérations spatiales » est gratuit à lire ici sur le web. Pour la pratiquer de manière interactive (un éditeur de code intégré et un tuteur IA 24/7) et déverrouiller le reste du cours R Academy, passe à CoddyKit PRO. Le cours R Academy comprend 4 leçons au total.
Qu'est-ce que j'apprendrai dans « Jointures et opérations spatiales » ?
Appliquez st_join(), st_intersection(), st_buffer() et st_distance(). Tu pratiques R Academy avec du code pratique que tu exécutes directement dans le navigateur, et un tuteur IA 24/7 répond à tes questions au fur et à mesure que tu avances dans la leçon.
Dois-je avoir de l'expérience pour commencer R Academy ?
Aucune expérience préalable n'est requise. R Academy sur CoddyKit est structuré pour les débutants jusqu'aux apprenants avancés, donc tu peux commencer ici ou depuis le début et avancer à ton rythme. Ceci est la leçon 3 sur 4.
Combien de temps prend la leçon « Jointures et opérations spatiales » ?
La plupart des leçons CoddyKit prennent environ 5–10 minutes. Chacune est courte et interactive, tu progresses régulièrement et tu repiques exactement où tu t'es arrêté sur le web et l'app.
Peux-tu écrire et exécuter du code dans cette leçon R Academy ?
Oui. Chaque leçon R Academy inclut un éditeur de code intégré, tu écris et exécutes du vrai code directement dans ton navigateur et tu reçois des retours IA instantanés — aucune configuration locale requise.
Toutes les leçons de ce cours
- Objets spatiaux simples avec le paquet sf
- Systèmes de coordonnées et projections
- Jointures et opérations spatiales
- Cartes interactives avec leaflet