raster – Calculate Mean of Same Month’s Raster Files Across Different Years

geotiff-tiffmeanrraster

I have monthly raster data (.tiff) from 2008 to 2020. Files nomenclature is as follows:

index_200801
index_200802
..
..
..
index_202005

I want to calculate mean of same months of different years.

I am trying to do it using grp function in R:

rast <- list.files((path="F:/Test/", pattern=".tiff$", full.names=TRUE) 
stk = stack(rast)
grp = rep(1:12, rep(??,12)

But I do not understand how to group the files.

Could anyone please help me in this and in exporting the plot.

In output, there should be 12 images, one for each month i.e., Jan (having mean of Jan 2008, Jan 2009…Jan 2020)..similarly for Feb…Dec.

Best Answer

This looks like you've taken my answer from here:

How stackApply function in R works to calculate monthly mean of daily .tiff files?

but not worked out how to construct the grouping variable for your example.

There's two ways:

One, assume your stack is in date order, and contains no missing months, starting at month 1, construct a sequence of the same length as your vector of raster files, and use mod-12 to make it repeat 1 to 12 enough times plus any bit at the end.

My sample data starts with 2006-01 and ends with 2010-06 so there's half a year to deal with at the end:

> head(rast)
[1] "./tiffs//index_X200601.tif" "./tiffs//index_X200602.tif"
[3] "./tiffs//index_X200603.tif" "./tiffs//index_X200604.tif"
[5] "./tiffs//index_X200605.tif" "./tiffs//index_X200606.tif"
> tail(rast)
[1] "./tiffs//index_X201001.tif" "./tiffs//index_X201002.tif"
[3] "./tiffs//index_X201003.tif" "./tiffs//index_X201004.tif"
[5] "./tiffs//index_X201005.tif" "./tiffs//index_X201006.tif"

And this expression will return a sequence of 1 to 12 and include the final 1 to 6 at the end:

> (0:(length(rast)-1)) %% 12  + 1
 [1]  1  2  3  4  5  6  7  8  9 10 11 12  1  2  3  4  5  6  7  8  9 10 11 12  1
[26]  2  3  4  5  6  7  8  9 10 11 12  1  2  3  4  5  6  7  8  9 10 11 12  1  2
[51]  3  4  5  6

Two, get the month from the filename itself. There's various ways of doing this, for example using substr to get a substring of the file name. For my files with my paths, I use substr(rast, 21,22) but your paths may put it in a different position.

> grp = substr(rast, 21,22)
> grp
 [1] "01" "02" "03" "04" "05" "06" "07" "08" "09" "10" "11" "12" "01" "02" "03"
[16] "04" "05" "06" "07" "08" "09" "10" "11" "12" "01" "02" "03" "04" "05" "06"
[31] "07" "08" "09" "10" "11" "12" "01" "02" "03" "04" "05" "06" "07" "08" "09"
[46] "10" "11" "12" "01" "02" "03" "04" "05" "06"

If your file names are varying lengths then you may need some sort of pattern matching selection via regexec to get to the month part of it.

Once done, use stackApply as in the linked question.

> monthmean = stackApply(stk, grp, mean)
> monthmean
class      : RasterBrick 
dimensions : 3, 4, 12, 12  (nrow, ncol, ncell, nlayers)
resolution : 0.25, 0.3333333  (x, y)
extent     : 0, 1, 0, 1  (xmin, xmax, ymin, ymax)
crs        : NA 
source     : memory
names      :    index_01,    index_02,    index_03,    index_04,    index_05,    index_06,    index_07,    index_08,    index_09,    index_10,    index_11,    index_12 
min values : 0.009314219, 0.009314219, 0.009314219, 0.009314219, 0.009314219, 0.009314219, 0.009314219, 0.009314219, 0.009314219, 0.009314219, 0.009314219, 0.009314219 
max values :   0.9669667,   0.9669667,   0.9669667,   0.9669667,   0.9669667,   0.9669667,   0.9669667,   0.9669667,   0.9669667,   0.9669667,   0.9669667,   0.9669667 

Note you should try and migrate your analysis to the terra package if possible rather than the older and less well-supported raster package.