
Working with spatial data in R

vector model, or a raster modelvector data, which is represented by points, lines, polygons (and combination of these)vector data are often saved as shapefiles, geoJSON files, or geopackage filesR, we use the simple features standard to work with vector data via {sf}.shp, .gpkg…), we read them with sf::read_sf()sf objects have three main components:
By the end of this week, you should be able to
raster or vector data (or both)raster objects with {terra}raster data with {tidyterra}Common Applications:


Common extensions include:
TIFF or “GeoTiff” is simply an image made of pixels
terra the “origin” of the matrix is the top-left corner
\[ \mathrm{resolution_x} = \frac{x_{max} - x_{min}}{n_{col}} \]
Q: How many coordinates does R need to store if you specify the origin, extent, and resolution?
A: One coordinate pair, lattitude and longitude for the origin

terra Packageterra Package: Examplerast()class : SpatRaster
size : 3600, 7200, 1 (nrow, ncol, nlyr)
resolution : 0.05, 0.05 (x, y)
extent : -180, 180, -90, 90 (xmin, xmax, ymin, ymax)
coord. ref. : lon/lat WGS 84 (EPSG:4326)
source : depth_raster.tif
name : depth_m
min value : -10273.276367
max value : 0.985951
Find info contained in the header with specific functions:
SpatExtent : -180, 180, -90, 90 (xmin, xmax, ymin, ymax)
[1] 0.05 0.05
[1] 3600 7200 1
[1] 25920000
[1] "depth_m"
The fastest way is to use the base plot() function
As with vector data, I can layer different pieces of my plot
Task: Produce a map of water depth around FL
crop()1Task: Build the same map, but only show shallow (depth > -100 m) waters
binary operatorsTask: Build the same map, but only show shallow (depth > -100 m) waters
NA{tidyterra}{tidyterra}
{tidyterra}: Common methods of the tidyverse for objects created with {terra}
The {tidyterra} package:
terra packagegeom_spatraster()){tidyterra}library(tidyterra) # Load terra
ggplot() + # Begin a ggplot
geom_spatraster(data = depth, # specify object to plot
aes(fill = depth_m)) + # specify layer to plot
geom_sf(data = FL_counties) # Add FL counties on top
tidyterraterra
All layers must have the same extent and resolution
terra# Let's read habitat suitability models for four sea turtle species
log <- rast("data/raw/AquaMaps/Caretta_caretta.tiff")
green <- rast("data/raw/AquaMaps/Chelonia_mydas.tiff")
leather <- rast("data/raw/AquaMaps/Dermochelys_coriacea.tiff")
hawk <- rast("data/raw/AquaMaps/Eretmochelys_imbricata.tiff")
# We can combine them together using the `c()` function
turtles <- c(log, green, leather, hawk)
turtlesclass : SpatRaster
size : 300, 720, 4 (nrow, ncol, nlyr)
resolution : 0.5, 0.5 (x, y)
extent : -180, 180, -75, 75 (xmin, xmax, ymin, ymax)
coord. ref. : lon/lat WGS 84 (EPSG:4326)
sources : Caretta_caretta.tiff
Chelonia_mydas.tiff
Dermochelys_coriacea.tiff
Eretmochelys_imbricata.tiff
names : Caretta_caretta, Chelonia_mydas, Dermoch~oriacea, Eretmoc~bricata
min values : 0.01, 0.01, 0.01, 0.01
max values : 1.00, 1.00, 1.00, 1.00
Calling plot() on a multi-layer raster shows us one sub-plot per layer
Task: Calculate the mean habitat suitability around FL waters
class : SpatRaster
size : 300, 720, 4 (nrow, ncol, nlyr)
resolution : 0.5, 0.5 (x, y)
extent : -180, 180, -75, 75 (xmin, xmax, ymin, ymax)
coord. ref. : lon/lat WGS 84 (EPSG:4326)
source(s) : memory
names : Caretta_caretta, Chelonia_mydas, Dermoch~oriacea, Eretmoc~bricata
min values : 0.51, 0.51, 0.55, 0.51
max values : 1.00, 1.00, 1.00, 1.00

Task: Calculate the mean habitat suitability around FL waters
turtle_habitat <- turtles |> # Start from turtles
# And pipe into filter()
filter(Caretta_caretta > 0.5,
Chelonia_mydas > 0.5,
Dermochelys_coriacea > 0.5,
Eretmochelys_imbricata > 0.5) |>
# Then crop it to FL counties
crop(st_buffer(FL_counties, dist = 100000)) |> # Any guesses on what st_buffer is doing?
mean()
terra Package:
{raster} packagerast() to read raster files (.tif, .tiff, .asc, .nc)tidyterra Package:
terra with tidyverse-friendly functionsterra for spatial operations (e.g., crop())tidyterra for attribute operations (e.g., filter(), mutate())c()mean(), sum(), etc. to aggregate across layersterra, tidyterra, and ggspatial