Skip to content

Instantly share code, notes, and snippets.

@benmarwick
Created April 27, 2018 22:17
Show Gist options
  • Save benmarwick/70f92dd61700abab1b590afa0040e3fa to your computer and use it in GitHub Desktop.
Save benmarwick/70f92dd61700abab1b590afa0040e3fa to your computer and use it in GitHub Desktop.
using sf for points in polygon spatial join
library(sf)
library(tidyverse)
# read in the shapefile first, that gives us the CRS for the analysis
polygons <- st_read("polygons.shp")
# read in the points
points <- read_csv('points.csv')
# convert the points to an sf object
points_sf <- st_as_sf(points, coords = c("decimalLongitude", "decimalLatitude"))
# set CRS for the points to be the same as shapefile
st_crs(points_sf) <- st_crs(polygons)
# plot to see how they relate
ggplot() +
geom_sf(data = polygons) +
geom_sf(data = points_sf) +
theme_minimal()
# some points are out of the polygon, lets filter out
# so we get only points in the polygon
points_sf_joined <-
st_join(points_sf, polygons) %>% # spatial join to get intersection of points and poly
filter(!is.na(rgn_name)) # rgn_name just one col from the polygon data that I chose to filter on, could use any. The idea is to get only the points that fall in the polygon
# plot again
ggplot() +
geom_sf(data = polygons) +
geom_sf(data = points_sf_joined) +
theme_minimal()
# we see only points in the polygon, great!
# the st_bbox method is less ideal because the bbox is the rectangle that the polygon fits in, not the exact shape of the polygon. With a spatial join, we can filter by location in/out of the exact shape of the polygon.
@geranwen
Copy link

geranwen commented Mar 9, 2021

This is EXACTLY what I needed. Thank you so much.

@markbneal
Copy link

Thumbs up! filter requirement was not obvious to me until I saw your code, so thanks.

@aito123
Copy link

aito123 commented May 24, 2022

Interesting solution, definitely going to apply it. Athough, like filter it changes the duplicated names like if there is a variable name in both dataframes sf it would rename it like name.x and name.y. Is there a more efficient way to "crop" just the points that are inside the polygons without altering the names? Thanks in advance.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment