Search code examples
rautomationrastershapefileclip

R: Iteratively crop and mask several rasters with a shapefile


I am having 20 raster layers and 1 shapefile. I would like to:

  1. crop and mask each raster iteratively (i.e., first crop and mask the first raster, then the second and so on)
  2. save each cropped raster with the same name as its original into a subfolder of the working directory.

I can do this for every raster (manually, one-by-one) but I would like to automate the process. My raster layers do not have the same extent, that's why I want to crop and mask them one-by-one (also they are large in size (mb) which means it would be difficult for my laptop to set the same extent and then clip them all together using the shapefile). Here is the code for doing this in a one-by-one manner:

library(terra)

setwd("path")

r1 = rast("path/a.tif")
r2 = rast("path/b.tif")
poly <- vect("path/poly.shp")

r1 <- crop(r1, 
           poly, 
           mask = T)

r2 <- crop(r2, 
           poly, 
           mask = T)

dir.create(file.path(getwd(), 'clip'), recursive = T)

writeRaster(r1, "path/clip/r1.tif")
writeRaster(r2, "path/clip/r2.tif")

From here you can download a small subset the data.


Solution

  • Perhaps something like this:

    library(terra)
    
    crop_poly <- vect(file.path(here::here(), "poly.shp"))
    
    filenames_in <- list.files(here::here(), pattern = "\\.tif$") 
    
    corpped_rasters <- filenames_in |>  
      # apply rast() on each filename in filenames_in list, 
      # returns list of rasters
      lapply(rast) |>
      # apply crop(), first param from input list (of rasters), 
      # pass on y and mask parameters
      lapply(crop, y = crop_poly, mask = T) 
    
    filenames_out <- file.path("clip", filenames_in)
    dir.create(file.path(here::here(), 'clip'))
    
    # apply writeRaster on pairs of list elements from corpped_rasters & filenames_out
    # writeRaster(corpped_rasters[[1]], filenames_out[[1]])
    # writeRaster(corpped_rasters[[2]], filenames_out[[2]])
    # ...
    mapply(writeRaster, corpped_rasters, filenames_out)