Search code examples
rautomationrasterterra

Automate the focal function so can be applied to every raster in the folder


In R, I am using the focal function to blur some rasters. SO far, I am reading each raster individually, I apply the focal (please see the code below) and then I move to the next raster etc. This process of reading and applying the function to each raster separately is time consuming because I have several rasters for a many study sites.

What I'd like to do, is to read the rasters located in a folder, and apply the focal function in an automated way. That is, the function should read each raster of the folder and then will apply exactly the code I am using for every raster. In this way, the only parameters I'll have to set would be the working directory.

This is what I'm doing so far:

library(terra)

wd = "C:/Users/nikos/OneDrive/Desktop/psf_paris2/"

# read the rasters
pop = rast(paste0(wd, "pop.tif"))

# focal for every raster
# raster named pop
for (i in seq(from = 0.2, to = 0.8, by = 0.2)) {
  
  print(i)
  
  gf <- focalMat(pop, i * 400, "Gauss")
  r_gf <- focal(pop, w = gf, na.rm = TRUE)

  r_gf = aggregate(r_gf, fact = 4, fun = "mean", cores = 8)
  
  stringedi = gsub("\\.", "", toString(format(i, nsmall = 2)))
  
  writeRaster(r_gf, 
              paste0("C:/Users/nikos/OneDrive/Desktop/psf_paris2/pop", 
                                  stringedi, ".tif"), 
              overwrite=TRUE)
}

Here is one raster:

pop = raster(new("RasterLayer", file = new(".RasterFile", name = "C:\\Users\\Geography\\Desktop\\focal\\pop.tif", 
    datanotation = "FLT4S", byteorder = "little", nodatavalue = -Inf, 
    NAchanged = FALSE, nbands = 1L, bandorder = "BIL", offset = 0L, 
    toptobottom = TRUE, blockrows = c(rows = 5L), blockcols = c(cols = 358L), 
    driver = "gdal", open = FALSE), data = new(".SingleLayerData", 
    values = logical(0), offset = 0, gain = 1, inmemory = FALSE, 
    fromdisk = TRUE, isfactor = FALSE, attributes = list(), haveminmax = TRUE, 
    min = 0.43411433696747, max = 355.74725341797, band = 1L, 
    unit = "", names = "pop"), legend = new(".RasterLegend", 
    type = character(0), values = logical(0), color = logical(0), 
    names = logical(0), colortable = logical(0)), title = character(0), 
    extent = new("Extent", xmin = 165700, xmax = 201500, ymin = 5735500, 
        ymax = 5769600), rotated = FALSE, rotation = new(".Rotation", 
        geotrans = numeric(0), transfun = function () 
        NULL), ncols = 358L, nrows = 341L, crs = new("CRS", projargs = "+proj=moll +lon_0=0 +x_0=0 +y_0=0 +datum=WGS84 +units=m +no_defs"), 
    srs = "+proj=moll +lon_0=0 +x_0=0 +y_0=0 +datum=WGS84 +units=m +no_defs", 
    history = list(), z = list()))

Solution

  • The solution to the files name problem:

    library(terra)
    library(purrr)
    library(fs)
    
    wd = "C:/Users/Geography/Desktop/focal/"
    
    # read the rasters
    pop = rast(paste0(wd, "pop.tif"))
    
    doStuff <- function(file){
      
      pic = rast(file)
      
      for (i in seq(from = 0.2, to = 0.8, by = 0.2)) {
        
        print(i)
        
        gf <- focalMat(pic, i * 400, "Gauss")
        r_gf <- focal(pic, w = gf, na.rm = TRUE)
        
        r_gf = aggregate(r_gf, fact = 4, fun = "mean", cores = 4)
    
        (stringedi = gsub("\\.", "", toString(format(i, nsmall = 2))))
        
        writeRaster(r_gf, 
                    paste0("C:/Users/Geography/Desktop/focal/", 
                           basename(fs::path_ext_remove(file)),
                           stringedi, ".tif"), 
                    overwrite=TRUE)
      }
      
    }
    
    list.files(wd, pattern = "tif$", full.names = TRUE) |>
      purrr::walk(doStuff)