Convert species range maps (shapefiles) to a site × species presence matrix. Sites can be points or hexagons.
range_maps_to_sites <- function(shp, sites, sp_col = "SCINAME") {
if (!requireNamespace("sf", quietly = TRUE)) install.packages("sf")
library(sf)
# Ensure same CRS
sites <- st_transform(sites, st_crs(shp))
# For each species, find intersecting sites
species <- unique(shp[[sp_col]])
mat <- do.call(cbind, lapply(species, function(sp) {
sp_poly <- shp[shp[[sp_col]] == sp, ]
presence <- lengths(st_intersects(sites, sp_poly)) > 0
as.integer(presence)
}))
colnames(mat) <- species
rownames(mat) <- seq_len(nrow(sites))
as.data.frame(mat)
}