0Pricing
R Academy · บทเรียน

การเชื่อมตารางและการดำเนินการเชิงพื้นที่

ใช้ st_join(), st_intersection(), st_buffer() และ st_distance()

การเชื่อมตารางและการดำเนินการเชิงพื้นที่ เป็นบทเรียน R Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 3 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน R Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส R Academy มีบทเรียนทั้งหมด 4 บทเรียน

การเชื่อมข้อมูลเชิงพื้นที่ด้วย st_join

st_join(x, y) ดำเนินการเชื่อมด้านซ้ายเชิงพื้นที่: สำหรับแต่ละฟีเจอร์ใน x ฟังก์ชันจะค้นหาฟีเจอร์ใน y ที่ตรงตามเพรดิเคตเชิงพื้นที่ (ค่าเริ่มต้นคือ st_intersects) แล้วเพิ่มแอตทริบิวต์ของฟีเจอร์เหล่านั้น หากตรงกันหลายรายการ จะเกิดหลายแถว

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: จุดอยู่ในรูปหลายเหลี่ยม

st_within(x, y) ส่งคืนเมทริกซ์แบบเบาบางของค่าตรรกะที่ระบุว่าแต่ละฟีเจอร์ใน x อยู่ภายในฟีเจอร์ใน y ทั้งหมดหรือไม่ ฟังก์ชันนี้เข้มงวดกว่า st_intersects เพราะการแตะขอบไม่นับรวม

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: การทดสอบการทับซ้อน

st_intersects(x, y) ส่งคืน TRUE เมื่อฟีเจอร์มีเรขาคณิตส่วนใดร่วมกัน ไม่ว่าจะเป็นขอบหรือพื้นที่ด้านใน นี่คือเพรดิเคตเชิงโทโพโลยีที่ยืดหยุ่นที่สุด ส่ง sparse = FALSE เพื่อรับเมทริกซ์ตรรกะแทนรายการเวกเตอร์ดัชนี

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: การสร้างบัฟเฟอร์

st_buffer(sf_obj, dist) สร้างรูปหลายเหลี่ยมบัฟเฟอร์รอบแต่ละฟีเจอร์ตามระยะทางที่ระบุ ใน CRS แบบภูมิศาสตร์ ระยะทางมีหน่วยเป็นองศา ส่วนใน CRS แบบฉายมีหน่วยเป็นเมตร ควรฉายข้อมูลก่อนสร้างบัฟเฟอร์เสมอเพื่อให้ได้ผลลัพธ์ที่แม่นยำ

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: พื้นที่รูปหลายเหลี่ยม

st_area(sf_obj) คำนวณพื้นที่ของรูปหลายเหลี่ยมแต่ละรูป ใน CRS แบบภูมิศาสตร์ ผลลัพธ์มีหน่วยเป็นสเตอเรเดียนซึ่งไม่เหมาะสำหรับใช้งานจริง ส่วนใน CRS แบบฉายที่ใช้หน่วยเมตร ผลลัพธ์มีหน่วยเป็นตารางเมตร ผลลัพธ์จะมีหน่วยกำกับจากแพ็กเกจ 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: ระยะทางแบบจับคู่

st_distance(x, y) คำนวณเมทริกซ์ระยะทางระหว่างฟีเจอร์ทั้งหมดใน x กับฟีเจอร์ทั้งหมดใน y บน WGS84 ฟังก์ชันนี้ใช้ระยะทางตามเส้นโค้งโลก ส่วนบน CRS แบบฉายจะใช้ระยะทางแบบยุคลิด ผลลัพธ์จะมีเมทาดาทา 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: การรวมเรขาคณิต

st_union(sf_obj) รวมฟีเจอร์ทั้งหมดเป็นเรขาคณิตเดียว โดยลบขอบเขตภายในออก เหมาะสำหรับสร้างรูปหลายเหลี่ยมเส้นขอบเดียวจากรูปหลายเหลี่ยมเขตการปกครองหลายรูป หรือรวมชุดบัฟเฟอร์เข้าด้วยกัน

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: การตัดขอบเขต

st_intersection(x, y) ส่งคืนส่วนตัดกันทางเรขาคณิตของฟีเจอร์แต่ละคู่ ซึ่งคือพื้นที่ที่เรขาคณิตทั้งสองมีร่วมกัน ใช้สำหรับตัดชั้นข้อมูลหนึ่งให้เหลือเท่าขอบเขตของอีกชั้นข้อมูล

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')

การรวมข้อมูลเชิงพื้นที่ด้วย dplyr

รวม st_join() กับ dplyr::group_by() และ summarise() เพื่อรวมข้อมูลจุดตามรูปหลายเหลี่ยม คอลัมน์เรขาคณิตจะถูกรวมโดยอัตโนมัติ (ค่าเริ่มต้นคือการรวมเรขาคณิตเข้าด้วยกัน) เมื่อจัดกลุ่มออบเจ็กต์ 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) ส่งคืนดัชนีของฟีเจอร์ที่ใกล้ที่สุดใน y สำหรับฟีเจอร์แต่ละรายการใน x เมื่อนำไปใช้ร่วมกับ st_distance() จะได้ทั้งฟีเจอร์ข้างเคียงที่ใกล้ที่สุดและระยะทาง เหมาะสำหรับปัญหาการจัดสรร

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))

กระบวนการทำงานจริง: สร้างบัฟเฟอร์และนับจำนวน

รูปแบบที่พบได้บ่อยในงานจริงคือ สร้างบัฟเฟอร์รอบชุดฟีเจอร์ (เช่น โรงเรียน) จากนั้นนับจำนวนจุดที่สนใจ (เช่น ป้ายรถโดยสาร) ที่อยู่ภายในบัฟเฟอร์แต่ละรายการ โดยใช้ st_join() และ 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)

ตรวจสอบความเข้าใจอย่างรวดเร็ว

คุณต้องการค้นหาฟีเจอร์รูปหลายเหลี่ยมทั้งหมดจากชั้นข้อมูล B ที่ทับซ้อนกับรูปหลายเหลี่ยมแต่ละรูปในชั้นข้อมูล A และเพิ่มแอตทริบิวต์ของ B ให้กับ A คุณควรใช้ฟังก์ชันใด

ทบทวน: การเชื่อมข้อมูลและการดำเนินการเชิงพื้นที่

ประเด็นสำคัญ:

  • st_join(x, y) — การเชื่อมด้านซ้ายเชิงพื้นที่โดยใช้เพรดิเคต (ค่าเริ่มต้นคือ st_intersects)
  • st_within() — เป็น TRUE เมื่อ x อยู่ภายใน y ทั้งหมด (ไม่รวมขอบเขต)
  • st_intersects() — เป็น TRUE เมื่อส่วนใด ๆ ของ x แตะ y (ยืดหยุ่นที่สุด)
  • st_buffer(sf_obj, dist) — สร้างบัฟเฟอร์ ควรใช้ CRS แบบฉายเพื่อให้บัฟเฟอร์มีระยะเป็นเมตรอย่างแม่นยำ
  • st_area() / st_distance() — คำนวณพื้นที่และระยะทาง (ควรฉายก่อนเพื่อความแม่นยำ)
  • st_union() — รวมฟีเจอร์ทั้งหมด; st_intersection() — ตัดชั้นข้อมูลหนึ่งให้ตรงกับอีกชั้นข้อมูล
  • st_nearest_feature(x, y) — ค้นหาฟีเจอร์ข้างเคียงที่ใกล้ที่สุด
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')

คำถามที่พบบ่อย

บทเรียน “การเชื่อมตารางและการดำเนินการเชิงพื้นที่” ฟรีหรือไม่

ใช่ — ข้อความเต็มของ “การเชื่อมตารางและการดำเนินการเชิงพื้นที่” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส R Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส R Academy มีบทเรียนทั้งหมด 4 บทเรียน

คุณจะเรียนรู้อะไรในบทเรียน “การเชื่อมตารางและการดำเนินการเชิงพื้นที่”

ใช้ st_join(), st_intersection(), st_buffer() และ st_distance() คุณปฏิบัติ R Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน

คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน R Academy หรือไม่

ไม่จำเป็นต้องมีประสบการณ์มาก่อน R Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 3 จากทั้งหมด 4 บทเรียน

บทเรียน “การเชื่อมตารางและการดำเนินการเชิงพื้นที่” ใช้เวลานานแค่ไหน

บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย

ฉันเขียนและรันโค้ดในบทเรียน R Academy นี้ได้ไหม

ได้ บทเรียน R Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ

บทเรียนทั้งหมดในหลักสูตรนี้

  1. ฟีเจอร์เชิงเรขาคณิตอย่างง่ายด้วยแพ็กเกจ sf
  2. ระบบพิกัดอ้างอิงและการฉายแผนที่
  3. การเชื่อมตารางและการดำเนินการเชิงพื้นที่
  4. แผนที่เชิงโต้ตอบด้วย leaflet
← กลับไปที่ R Academy