Räumliche Joins und Operationen
Wenden Sie st_join(), st_intersection(), st_buffer() und st_distance() an
Räumliche Joins und Operationen ist eine kostenlose R Academy-Lektion auf CoddyKit. Dies ist Lektion 3 von 4. Du kannst die komplette Lektion unten kostenlos lesen – dann übst du sie direkt im Browser mit einem integrierten Code-Editor und einem KI-Tutor rund um die Uhr. Sie ist Teil des R Academy-Lernpfads, und dein Fortschritt wird über Web und CoddyKit-App synchronisiert. Der R Academy-Kurs umfasst insgesamt 4 Lektionen.
Räumliche Joins mit st_join
st_join(x, y) führt einen räumlichen Left Join durch: Für jedes Feature in x werden die Features in y gesucht, die ein räumliches Prädikat erfüllen (Standard: st_intersects), und deren Attribute angehängt. Mehrere Treffer erzeugen mehrere Zeilen.
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: Punkt-in-Polygon
st_within(x, y) gibt eine dünn besetzte Matrix logischer Werte zurück, die angibt, ob jedes Feature in x vollständig innerhalb eines Features in y liegt. Die Funktion ist strenger als st_intersects – Berührungen am Rand zählen nicht.
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: Überlappung prüfen
st_intersects(x, y) gibt TRUE zurück, wenn Features irgendeine Geometrie teilen – am Rand oder im Inneren. Es ist das großzügigste topologische Prädikat. Mit sparse = FALSE erhalten Sie eine logische Matrix anstelle einer Liste von Indexvektoren.
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: Puffer erstellen
st_buffer(sf_obj, dist) erstellt um jedes Feature ein Pufferpolygon mit dem angegebenen Abstand. In einem geografischen CRS wird der Abstand in Grad angegeben, in einem projizierten CRS in Metern – reprojizieren Sie daher für genaue Ergebnisse immer vor dem Puffern.
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: Polygonflächen
st_area(sf_obj) berechnet die Fläche jedes Polygons. In einem geografischen CRS werden Werte in Steradiant zurückgegeben (nicht sinnvoll); in einem projizierten CRS mit Meter-Einheiten in Quadratmetern. Die Ergebnisse enthalten Einheiten aus dem Paket 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: Paarweise Entfernungen
st_distance(x, y) berechnet eine Matrix der Entfernungen zwischen allen Features in x und allen Features in y. Bei WGS84 werden geodätische Entfernungen verwendet, bei einem projizierten CRS euklidische Entfernungen. Die Ergebnisse enthalten units-Metadaten.
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: Geometrien auflösen
st_union(sf_obj) führt alle Features zu einer einzigen Geometrie zusammen und löst innere Grenzen auf. Dies ist nützlich, um aus mehreren Landkreis-Polygonen ein einzelnes Umrisspolygon zu erstellen oder eine Gruppe von Puffern zu vereinigen.
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: Ausschneiden
st_intersection(x, y) gibt den geometrischen Schnitt jedes Featurepaars zurück – also den Bereich, den beide Geometrien gemeinsam haben. Die Funktion wird verwendet, um einen Layer auf die Ausdehnung eines anderen zu beschneiden.
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')Räumliche Aggregation mit dplyr
Kombinieren Sie st_join() mit dplyr::group_by() und summarise(), um Punktdaten nach Polygonen zu aggregieren. Die Geometriespalte wird beim Gruppieren eines sf-Objekts automatisch zusammengefasst (standardmäßig durch Vereinigen).
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) gibt für jedes Feature in x den Index des nächstgelegenen Features in y zurück. In Kombination mit st_distance() erhalten Sie sowohl den nächsten Nachbarn als auch dessen Entfernung – nützlich für Zuordnungsprobleme.
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))Praktischer Workflow: Puffern und zählen
Ein häufiges Muster aus der Praxis: Puffern Sie eine Gruppe von Features (z. B. Schulen) und zählen Sie anschließend mit st_join() und dplyr::count(), wie viele Points of Interest (z. B. Bushaltestellen) in jeden Puffer fallen.
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)Schnelltest
Sie möchten alle Polygon-Features aus Layer B finden, die sich mit jedem Polygon in Layer A überschneiden, und die Attribute von B an A anhängen. Welche Funktion sollten Sie verwenden?
Zusammenfassung: Räumliche Joins und Operationen
Wichtigste Erkenntnisse:
st_join(x, y)– räumlicher Left Join mit einem Prädikat (Standard:st_intersects)st_within()– TRUE, wenn x vollständig innerhalb von y liegt (Rand ausgeschlossen)st_intersects()– TRUE, wenn irgendein Teil von x y berührt (am großzügigsten)st_buffer(sf_obj, dist)– Puffer erstellen; für metergenaue Puffer ein projiziertes CRS verwendenst_area()/st_distance()– Flächen und Entfernungen berechnen (für Genauigkeit zuerst reprojizieren)st_union()– alle Features auflösen;st_intersection()– einen Layer auf einen anderen beschneidenst_nearest_feature(x, y)– den nächsten Nachbarn ermitteln
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')Häufig gestellte Fragen
Ist die Lektion „Räumliche Joins und Operationen“ kostenlos?
Ja — der vollständige Text von „Räumliche Joins und Operationen“ ist hier im Web kostenlos zu lesen. Um sie interaktiv zu üben (integrierter Code-Editor und 24/7 KI-Tutor) und den Rest des R Academy-Kurses freizuschalten, upgrade auf CoddyKit PRO. Der R Academy-Kurs umfasst insgesamt 4 Lektionen.
Was lerne ich in „Räumliche Joins und Operationen“?
Wenden Sie st_join(), st_intersection(), st_buffer() und st_distance() an Du übst R Academy mit praktischem Code, den du direkt im Browser ausführst, und ein 24/7 KI-Tutor beantwortet deine Fragen während du die Lektion bearbeitest.
Brauche ich Erfahrung, um R Academy zu starten?
Keine Vorkenntnisse erforderlich. R Academy auf CoddyKit ist für Anfänger bis fortgeschrittene Lernende strukturiert, sodass du hier starten oder von Anfang an beginnen und in deinem eigenen Tempo voranschreiten kannst. Dies ist Lektion 3 von 4.
Wie lange dauert die Lektion „Räumliche Joins und Operationen“?
Die meisten CoddyKit-Lektionen dauern etwa 5–10 Minuten. Jede ist kompakt und interaktiv, sodass du stetig Fortschritte machst und genau dort weitermachst, wo du aufgehört hast – im Web und in der App.
Kann ich in dieser R Academy-Lektion Code schreiben und ausführen?
Ja. Jede R Academy-Lektion enthält einen integrierten Code-Editor, sodass du echten Code direkt in deinem Browser schreibst und ausführst und sofort KI-Feedback erhältst — ohne lokale Einrichtung erforderlich.
Alle Lektionen in diesem Kurs
- Simple Features mit dem Paket sf
- Koordinatenreferenzsysteme und Projektionen
- Räumliche Joins und Operationen
- Interaktive Karten mit leaflet