I have a raster brick/stack (using the raster package) in R for 45 years of annual rainfall data from 1970 to 2015. I want to calculate mean, median and standard deviation for a given year e.g. 2015 using the last 5 years, 10 years, 15 years, 20 years, 30 years. I want to do it from 2000 to 2015, where this processes repeated for every year using the stacked data and save the newly derived rasters for a given year. This the example code. Any help is greatly appreciated.
raster <- raster(ncol=10, nrow=10)
raster_brick <- brick( sapply(1:45, function(i) setValues(r, rnorm(ncell(r), i, 3))))
plot(raster_brick)
str(raster_brick)
To achieve this task, we can use the calc
function from the raster package. We also need to know how to subset the RasterBrick
object.
library(raster)
set.seed(123)
r <- raster(ncol=10, nrow=10)
r_brick <- brick(sapply(1:45, function(i) setValues(r, rnorm(ncell(r), i, 3))))
calc
can apply a function for all layers in a RasterBrick
object. The end result is a raster layer.
# Calculate mean
r_mean <- calc(r_brick, mean)
# Calculate median
r_median <- calc(r_brick, median)
# Calculate sd
r_sd <- calc(r_brick, sd)
Notice that r_mean
, r_median
, and r_sd
are all RasterLayer
.
We can use the index to subset the layer. For example,
r_sub <- r_brick[[1:3]]
r_sub
is the first three layers of r_brick
Knowing the technique of calc
and subset, we can design a function to conduct the analysis.
The first thing to do is create a vector serving as a reference to year and index.
# Create the index
ind <- 1:45
names(ind) <- 1971:2015
Calling the year number to ind
will return the index. For example,
# Get the index of 2015
ind[as.character(2015)]
#2015
# 45
Now design the function, which has five arguments
end_year
: The end year of analysis
n_year
: The last n
year in terms of the end year
FUN
: A function, such as mean
, median
, and sd
index
: The year index (ind
)
ras_brick
: RasterBrick
to work with
# Define the function
raster_stat <- function(end_year, n_year, FUN, index, ras_brick){
# Subset the raster
index_temp <- index[as.character((end_year - n_year + 1):end_year)]
ras_brick_temp <- ras_brick[[index_temp]]
# Calculate the statistics
ras_result <- calc(ras_brick_temp, FUN)
# Set the name
names(ras_result) <- paste("Y", end_year, n_year, substitute(FUN), sep = "_")
return(ras_result)
}
Now we can test the function.
raster_stat(2015, 5, FUN = sd, index = ind, ras_brick = r_brick)
#class : RasterLayer
#dimensions : 10, 10, 100 (nrow, ncol, ncell)
#resolution : 36, 18 (x, y)
#extent : -180, 180, -90, 90 (xmin, xmax, ymin, ymax)
#coord. ref. : +proj=longlat +datum=WGS84 +ellps=WGS84 +towgs84=0,0,0
#data source : in memory
#names : Y_2015_5_sd
#values : 12.05333, 14.61298 (min, max)
Notice that the result of the raster_stat
function has the name Y_2015_5_sd
. This is helpful to identify which end_year
, n_year
, and FUN
was applied.
We can use for loop to apply raster_stat
through all end_year
and n_year
. Here is an example calculating the mean
.
# Set the range of end_year and n_year
end_year_vec <- 2000:2015
n_year_vec <- c(5, 10 , 15, 20, 30)
# Create an empty list to store result
r_mean_list <- list()
for (i in end_year_vec){
for(j in n_year_vec){
result_temp <- raster_stat(end_year = i, n_year = j, FUN = mean,
index = ind, ras_brick = r_brick)
# Add the raster layer to the result_list
r_mean_list[[names(result_temp)]] <- result_temp
}
}
All the results are stored in r_mean_list
with a unique name. We can use the same approach for median
and sd
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With