R Terra – Renaming and Exporting a List of Rasters Using Terra in R

rterra

I've a list of hundreds of rasters that I've renamed, but when I export using writeRaster, the filenames have not changed.

For example:

library(terra)
library(tidyverse)
# all the of the packages I have loaded during actual work session... 
# if (!require("pacman")) install.packages("pacman"); library(pacman)
# p_load(here, tidyverse, sf,lubridate, raster, terra, janitor)

# read  list of files
(file_list <- list.files(here("test_set"), 
                         pattern="tif$", full.names = TRUE, recursive=FALSE))
# get names from list 
(file_names <- tools::file_path_sans_ext(list.files(here("test_set"), 
                                                    pattern="tif$", full.names = FALSE)) %>% 
    # remove everything after 1st underscore 
    str_extract("[^_]+"))
# read list of rasters
(r <- map(file_list, rast))

# rename the list 
(names(r) <- file_names)

map(r, function (i) 
  writeRaster(i, filename=paste0(here("test_set/new_names//"), names(i),".tif"), overwrite=TRUE))

I'd like to write the rasters to disk using the shortened names.

Best Answer

You are really over complicating this endeavor. This can easily be done with an iterator (for, lapply, ...) by simply operating on the vector of raster names.

library(terra)
library(stringr)
in.dir <- "C:/inrast"
out.dir <- "C:/outrast"

file_list <- list.files(in.dir, "tif$", full.names = TRUE)

lapply(file_list, function(i) { 
 writeRaster(rast(i), file.path(out.dir, 
   paste0(str_extract(basename(i), "[^_]+"), ".tif")))
  })  

So, in unpacking this code, lapply is acting as an iterator on the file_list vector of raster names. We are reading the raster on-the-fly using terra::rast within terra::writeRaster. The raster is being written to the out.dir (just to keep results separate). I am using the same syntax for stringr::str_extract and basename just extracts the end of the path name.

Here is a break down the nested function calls used in naming the new raster;

( x <- "C:/indir/file01_to_rename.tif" )
    # "C:/indir/file01_to_rename.tif"
( x <- basename(x) )
    # "file01_to_rename.tif"
( x <- str_extract(x, "[^_]+") ) 
    # "file01"
file.path("C:/outrast", paste0(x, ".tif"))
    # "C:/outrast/file01.tif"

Now put together, if the paths and names are included

file.path("C:/outrast", 
  paste0(str_extract(basename("C:/indir/file01_to_rename.tif"), 
    "[^_]+"), ".tif"))
      # "C:/outrast/file01.tif"