Search code examples
rrasterfile-rename

How to move month digits after year digits for multiple filenames in a folder with R?


I have a folder with multiple raster .tif files from January 1950 to December 2018. However, they are named with the month first and then the year (see below):

[1] "./WI_only_cmi60_01_1950.tif" "./WI_only_cmi60_01_1951.tif" "./WI_only_cmi60_01_1952.tif"

[4] "./WI_only_cmi60_01_1953.tif" "./WI_only_cmi60_01_1954.tif" "./WI_only_cmi60_01_1955.tif"

[7] "./WI_only_cmi60_01_1956.tif" "./WI_only_cmi60_01_1957.tif" "./WI_only_cmi60_01_1958.tif"

...


[820] "./WI_only_cmi60_12_2010.tif" "./WI_only_cmi60_12_2011.tif" "./WI_only_cmi60_12_2012.tif"

[823] "./WI_only_cmi60_12_2013.tif" "./WI_only_cmi60_12_2014.tif" "./WI_only_cmi60_12_2015.tif"

[826] "./WI_only_cmi60_12_2016.tif" "./WI_only_cmi60_12_2017.tif" "./WI_only_cmi60_12_2018.tif"

When I bring these into R and use the Raster package to stack these:

# list tif files in working directory
tifs <- list.files(pattern = ".tif$", full.names = TRUE)

# stack tifs in working directory
rstack <- stack(tifs)

They are ordered with all the January .tif files first followed by all the February .tif files etc when I need them for each year then each month (so chronologically ordered from January 1950 - December 2018).

Is there a way to rename these files where the order of the filenames can be rearranged so character 15 and 16 of each filename is moved after the year characters (18, 19, 20, 21)?

i.e. the first filename listed would change from

"./WI_only_cmi60_01_1950.tif"

to

"./WI_only_cmi60_1950_01.tif"

Solution

  • I would not rename the files, but instead sort the filenames appropriately. That should be a better approach in the long run for reproducibility and updating.

    Example (unsorted)

    ff <- c("./WI_only_cmi60_01_1950.tif","./WI_only_cmi60_01_1951.tif", "./WI_only_cmi60_01_1952.tif", 
    "./WI_only_cmi60_06_1950.tif", "./WI_only_cmi60_06_1951.tif", "./WI_only_cmi60_06_1952.tif", 
    "./WI_only_cmi60_12_1950.tif", "./WI_only_cmi60_12_1951.tif", "./WI_only_cmi60_12_1952.tif")
    

    Using Akrun's expression

    i <- sub("(\\d+)_(\\d+)(\\.tif)", "\\2_\\1\\3", ff)
    fs <- ff[order(i)]
    fs
    #[1] "./WI_only_cmi60_01_1950.tif" "./WI_only_cmi60_06_1950.tif"
    #[3] "./WI_only_cmi60_12_1950.tif" "./WI_only_cmi60_01_1951.tif"
    #[5] "./WI_only_cmi60_06_1951.tif" "./WI_only_cmi60_12_1951.tif"
    #[7] "./WI_only_cmi60_01_1952.tif" "./WI_only_cmi60_06_1952.tif"
    #[9] "./WI_only_cmi60_12_1952.tif"
    

    A more basic approach to achieve the same

    x <- gsub("WI_only_cmi60_", "", basename(ff))
    d <- paste(substr(x, 4, 7), substr(x, 1, 2), sep="-")
    i <- order(d)
    ff[i]
    

    Given that the pattern seems to be rather simple (69 years, 12 months each) you could also do (with all your files)

    i <- rep(1:69, 12)
    fs <- ff[i]
    

    (always double check the results!)