Search code examples
rloopsnamesterra

Renaming each band of a multiband raster when exporting as separate individual rasters using r terra package


I'm writing some code that takes a multiband raster, masks and resamples it by a reference raster, then exports and saves individual rasters for each band all within the terra package; however the names of the output rasters are giving me issues.

My code is currently:

#load library
library(terra)

#Define multiband raster path
multiband_raster_path <- "mypath.tif"

#load path raster to mask by
mask_raster_path <- "mypath.tif"

#Define Output Folder
output_directory <- "mypath_output"

#load mask raster
mask_raster <- terra::rast(mask_raster_path)

#load multiband raster
multiband_raster <- terra::rast(multiband_raster_path)

#crop multiband raster to make analysis quicker
multiband_raster <- terra::crop(multiband_raster, mask_raster)

#reproject, mask and resample multi band raster
multiband_raster <- terra::project(multiband_raster, mask_raster)
masked_raster <- terra::mask(multiband_raster, mask_raster)
resampled_raster <- terra::resample(masked_raster, mask_raster)

#define number of bands
num_bands <- terra::nlyr(resampled_raster)

# Loop through each band and save it as a separate raster
for (i in 1:num_bands) {
# Extract the i-th band
single_band <- resampled_raster[[i]]
# Define the output file path
output_file_path <- file.path(output_directory, paste0("GFDL_SSP3_2040_BIOCLIM_", i, ".tif"))
# Save the single band raster
writeRaster(single_band, output_file_path, overwrite=TRUE)

This is all working fine but I want to change the names of the individual rasters to match the file names I am designating them (E.g., GFDL_SSP3_2040_BIOCLIM_1; GFDL_SSP3_2040_BIOCLIM_2 etc). Currently they have the name of the specific band of the multiband raster input (e.g. wc2.1_30s_bioc_GFDL-ESM4_ssp370_2021-2040_1).

I think its related to the terra::names() function, but I'm not sure how to insert it into the loop to automate the renaming.

Any help would be hugely appreciated!


Solution

  • Using terra::set.names

    for (i in 1:nlyr(nineteen_band_rast)) {
      set.names(nineteen_band_rast, value = letters[i], index = i)
      }
    names(nineteen_band_rast)
     [1] "a" "b" "c" "d" "e" "f" "g" "h" "i" "j" "k" "l" "m" "n" "o" "p" "q" "r" "s"
    

    So, you create a character vector of your desired files_names <- c('file1', ..., and slip the set.names into your loop prior to write.

    Well, actually, given the structure above, rename prior to the loop,

    set.names(x, value = files_names, index=1:nlyr(x), validate=FALSE)
    

    And in your loop the <- file.path(output_directory becomes file.path(output_directory(paste0(names(nineteen_band_rast[i]), i, '.tif')))

    And you might comment as to why you want these as single band files rather than layers.