1

I have several raster files which I am passing a Gaussian filter and then I aggregate them based on a coarse resolution raster called ntl. I created this for loop but I don't know how to exclude the ntl raster from the loop. I have tried something like this, or this, and other thing but I am guessing I am doing something wrong because I get all sort of error depending on what I am trying. Here is the code:

wd = "path/"

ntl = rast(paste0(wd, "ntl.tif"))

v <- vect(paste0(wd, "lc.shp"))

doStuff <- function(file){
  
  pic = rast(file)
  
  for (i in seq(from = 0.3, to = 3, by = 0.1)) {
    
    print(i)
    
    gf <- focalMat(pic, i * res(ntl), "Gauss")
    r_gf <- focal(pic, w = gf, na.rm = TRUE)
    
    r_gf = exact_resample(r_gf, ntl, fun = 'mean', coverage_area = FALSE)
    
    r_gf <- mask(r_gf, v)
    ext(r_gf) <- ext(ntl)
    
    (stringedi = gsub("\\.", "", toString(format(i, nsmall = 2))))
    
    writeRaster(r_gf, 
                paste0("path/", 
                       basename(fs::path_ext_remove(file)),
                       stringedi, ".tif"), 
                overwrite=TRUE)
  }
  
}

list.files(wd, pattern = "tif$", full.names = TRUE) |>
  purrr::walk(doStuff)
Nikos
  • 426
  • 2
  • 10

2 Answers2

1

You can either separate ntl.tif from your other .tif files so that list.files() doesn't see it, or a simple approach is to add an if statement that checks file in your function, i.e.

doStuff <- function(file){
  if (file != file.path(wd, "ntl.tif")) {
    pic = rast(file)
  
    for (i in seq(from = 0.3, to = 3, by = 0.1)) {
      
      print(i)
      
      gf <- focalMat(pic, i * res(ntl), "Gauss")
      r_gf <- focal(pic, w = gf, na.rm = TRUE)
      
      r_gf = exact_resample(r_gf, ntl, fun = 'mean', coverage_area = FALSE)
      
      r_gf <- mask(r_gf, v)
      ext(r_gf) <- ext(ntl)
      
      (stringedi = gsub("\\.", "", toString(format(i, nsmall = 2))))
      
      writeRaster(r_gf, 
                  paste0("path/", 
                        basename(fs::path_ext_remove(file)),
                        stringedi, ".tif"), 
                  overwrite=TRUE)
    }
  }
}

Edit:

Since you are experiencing an error exactly at the ntl.tif file, and the above does not work for some reason, I would recommend removing it from the list.files call, so that ntl.tif is never walked over. One approach to doing this is:

files <- list.files(wd, pattern = "tif$", full.names = TRUE)
files <- files[-grepl("^ntl\\.tif$", files)]
purrr::walk(files, doStuff)

If that does not work, and you still receive the Error in map(): i In index: 5. Caused by error: ! [focal] not a meanigful window error, replace grepl with the index causing issues (in this case 5) and see if that continues.

Justin Singh-M.
  • 378
  • 2
  • 8
  • I tried your code and it still reads the ntl raster. Basically, my code reads each raster (based on their name) and performs the analysis inside the `for` loop. When ntl's turn comes it throws an error and the loop stops, but the raster data that their letter starts after the letter n (e.g., I have a raster called pop) they are automatically excluded from the loop because it stoped the moment ntl's turn came. – Nikos Mar 24 '23 at 21:14
  • @Nikos What error is returned? Why not just remove `path/to/ntl.tif` from the `list.files()` call, then call `purrr::walk`? – Justin Singh-M. Mar 24 '23 at 23:48
  • The error returns `Error in `map()`: i In index: 5. Caused by error: ! [focal] not a meanigful window`. And as I said, this because the code reads the ntl image and tries to apply the Gaussian filter. – Nikos Mar 25 '23 at 09:54
  • Please see my edit. If you are still receiving an error, then `ntl.tif` is not the issue. – Justin Singh-M. Mar 25 '23 at 14:36
  • Singh-M it worked using the index and not the `grepl`. I posted the complete code below as an answer. – Nikos Mar 25 '23 at 17:29
1

Thanks to the answer of @Justin Singh-M, I managed to solve the issue.

wd = "path/"

ntl = rast(paste0(wd, "ntl.tif"))

v <- vect(paste0(wd, "lc.shp"))

doStuff <- function(file){
  
  pic = rast(file)
  
  for (i in seq(from = 0.3, to = 3, by = 0.1)) {
    
    print(i)
    
    gf <- focalMat(pic, i * res(ntl), "Gauss")
    r_gf <- focal(pic, w = gf, na.rm = TRUE)
    
    r_gf = exact_resample(r_gf, ntl, fun = 'mean', coverage_area = FALSE)
    
    r_gf <- mask(r_gf, v)
    ext(r_gf) <- ext(ntl)
    
    (stringedi = gsub("\\.", "", toString(format(i, nsmall = 2))))
    
    writeRaster(r_gf, 
                paste0(wd, 
                       basename(fs::path_ext_remove(file)),
                       stringedi, ".tif"), 
                overwrite=TRUE)
  }
  
}

files <- list.files(wd, pattern = "tif$", full.names = TRUE)
files <- files[-(2)] # the number represents the image that should be dropped from the list
purrr::walk(files, doStuff)
Nikos
  • 426
  • 2
  • 10