Search code examples
rloopsstackmatchraster

Resample and matching raster stack using loop in R


I aim to combine biodiversity data with land cover information (rasters and vectors). However, I need to match the resolution, extent, CRS, and dimensions of each raster (predictor variables) with my biodiversity data (answer variables). I had succeed to do it individually but there are six rasters. Although, when I try a loop for the raster stack. I got some errors.

 

library(terra)
library(raster)
#Create a raster stack with land cover predictors:
CDI_stack<-raster::stack(list.files(path = dir_Proj1, pattern='.tif', full.names=T))
#Convert to cylindrical equal area projection
equalareaproj<-"+proj=cea +lon_0=0 +lat_ts=30 +x_0=0 +y_0=0 +datum=WGS84 +units=m +no_defs"
crs(CDI_stack, warn=FALSE)<-equalareaproj
#Raster with standard dimension, resolution, extention and CRS
standard<-terra::subset(study_area, 2) 
#Loop for the raster stack
for(i in 1:length(CDI_stack@layers)){
  #Creating a single raster with each layer to maintain values
  CDI_layer<-terra::rast(terra::subset(CDI_stack, i)) 
  #Matching a raster extention individually
  CDI_layer<-ext(standard) 
  #Cropping it with standard raster to reduce matching error
  raster::crop(CDI_layer[i],standard) 
  #Resample resolution 
  terra::resample(CDI_layer[i], standard, method= "near", threads= T) 
  #Write the raster:
  return(writeRaster(Resampled_layer, 
                     filename=paste0("~/Land use/Chronic_Anthropogenic_Disturbance_Surface/", CDI_layer[i]),
                     format="GTiff", overwrite=TRUE))
  }

I found these errors:

Error in h(simpleError(msg, call)) : 
 error evaluating argument 'x' in method selection for function 'crop': 'this S4 class is not subsettable
Error in (function (classes, fdef, mtable)  : 
  unable to find an inherited method for function ‘crop’ for signature ‘"numeric"’

I would like to know if there's any complication to use raster stack or whether I am doing any code step wrongly. I expect to found the correction on the code or of the use of class object.

Please, I hope for your support. Thank you! G.


Solution

  • Thank you for your advice, Mr. Hijimans. I found too many errors. When we do it directly with the raster stack the R returns that the method for the function 'resample' does not work on RasterStack class (see below). As a stack can have multiple layers, the loop simplified the process rather to work on each one of them. I preferred to work with a list from the raster stack than the stack, it worked better in the loop. Also, I used a vector to crop the raster, it preserved raster values (avoiding return NA).

    rc <- terra::resample(CDI_stack, standard, method= "bilinear", threads= T)
    Error in (function (classes, fdef, mtable)  : 
      unable to find an inherited method for function ‘resample’ for signature ‘"RasterStack", "SpatRaster"’
        
    #Create a list from the stack with land cover predictors:
    
    CDI_list<-terra::as.list(CDI_stack)  
    
    rm(study_area,CDI_stack)
    
    #Create a list to store the results
    results <- list()
    
    #Loop for each SpatRaster from the list
    for(i in 1:length(CDI_list)) {
      r<-rast(CDI_list[[i]]) # create a raster for each layer
      ext(r) <-ext(standard)  # redefine extension for each layer
      #Crop rasters using the vector to avoid 'NA' values
      rc <- terra::crop(r, standard_vec)
      #Resample rasters following standard parameters
      rc <- terra::resample(rc, standard, method= "bilinear", threads= T)
      #Rewrite the list layers with the result     
      results[[i]] <- rc 
    }
    
    #Check the values
    results[[4]]
    #Rasterize the list to save it as a data frame
    resampled<-rast(results)
    df<-as.data.frame(resampled)
    summary(df)
    #Save the data frame in the project directory
    data.table::fwrite(df, "~/Land use/DATASETS/resampled.csv")