Custom function changes the names of the exported files

I have several raster layers so I created a function that performs some analysis but it changes the names of the exported files. For example, for one of the rasters I have, I want the names of the files to be pop020.tif, pop040.tif etc, that, the 3 digit number to be right after the name of file.
Instead, the function moves the 3 digit number like pop.tif020. How can I place the 3 digit number to be right after the name of the file?

library(terra)

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

# 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 = 8)
    
    r_gf <- crop(r_gf, ext(v))
    r_gf <- mask(r_gf, v)
    
    stringedi = gsub("\\.", "", toString(format(i, nsmall = 2)))
    
    writeRaster(r_gf, 
                paste0("C:/Users/nikos/OneDrive/Desktop/psf_paris2/", basename(file),
                       stringedi, ".tif"), 
                overwrite=TRUE)
  }
  
}

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

One raster as an example:

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()))

To convert the raster to spatraster:
pop = rast(pop)

add library(fs) to use convenient file system functions.

(file <- file.path("some_folder","afile.tif"))
(i <- .3)
(stringedi = gsub("\\.", "", toString(format(i, nsmall = 2))))
paste0("C:/Users/nikos/OneDrive/Desktop/psf_paris2/", 
       basename(file),
       stringedi, ".tif")
paste0("C:/Users/nikos/OneDrive/Desktop/psf_paris2/", 
       basename(fs::path_ext_remove(file)),
       stringedi, ".tif")

@nirgrahamuk I just realized that I didn't include in the question that I have multiple rasters on which I do the same analysis (I did edit the question).

As for your code, it runs but at the end it shows me a file named pop.tif030 (single image instead of 4), even though in the console it seems to run more times (4 to be exact). Please see below:
Screenshot 2023-03-13 115442
This is what i did based on your code:

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)
    
    (file <- file.path(paste0(wd),"pop.tif"))
    (i <- .3)
    (stringedi = gsub("\\.", "", toString(format(i, nsmall = 2))))
    paste0("C:/Users/Geography/Desktop/focal/", 
           basename(file),
           stringedi, ".tif")
    paste0("C:/Users/Geography/Desktop/focal/", 
           basename(fs::path_ext_remove(file)),
           stringedi, ".tif")
    
    writeRaster(r_gf, 
                  paste0("C:/Users/Geography/Desktop/focal/", basename(file),
                       stringedi, ".tif"), 
                overwrite=TRUE)
  }
  
}

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

The output, is one image, named pop.tif030. 030 is not even in the values of i I set in for (i in seq(from = 0.2, to = 0.8, by = 0.2)). Am I missing something?

your question was focused on file names, so I ignored the rest of the content; and focused on the element that controls filenames. I wasn't suggesting that you hardcode i to .3 or file to any particular value; that was by way of setting up an example that was relevant to your setup.
There is no need to have two paste0's , the first was there to show you what you were doing...
the second was to show you what you could do instead.

Hope this helps !

1 Like

Sure it helped. Here is the complete code:

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)

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.

If you have a query related to it or one of the replies, start a new topic and refer back with a link.