I have created a for
loop to bring in climate data from a series of rasters. Each variable has data for four months with each month having a raster for each of 30 years of data. The loop below finds all rasters with the same month (of the same variable) and calculates the average across all years. Finally, the loop stacks the four monthly averaged rasters under an object with the variable name.
I have more variables than are shown below in clim.vars
and I would like to be able to run any combination of variables by only changing the clim.vars
variable. This loop does a good job at working through the variables but my end goal is to create a stacked raster that contains all variables and all months with each layer named as "variable_month"
. This is where I seem to get stuck. I have tried multiple ways to combine all the variables after the loop but I can't quite get it. I think the issue is in the fact that clim.vars
is a character vector, not an object vector. I have tried changing it with as.name()
and mget()
clim.vars <- c("max_Tmean", "mean_RH", "min_RH", "mean_Tmax")
for(var in clim.vars){
June <- rast(list.files(paste0("./Data/", var, "/Rasters"),
full.names = TRUE,
pattern = glob2rx(paste0(var, "_June_*.tif$")))) %>%
crop(vect(SA)) %>% mask(vect(SA)) %>% mean()
July <- rast(list.files(paste0("./Data/", var, "/Rasters"),
full.names = TRUE,
pattern = glob2rx(paste0(var, "_July_*.tif$")))) %>%
crop(vect(SA)) %>% mask(vect(SA)) %>% mean()
August <- rast(list.files(paste0("./Data/", var, "/Rasters"),
full.names = TRUE,
pattern = glob2rx(paste0(var, "_August_*.tif$")))) %>%
crop(vect(SA)) %>% mask(vect(SA)) %>% mean()
September <- rast(list.files(paste0("./Data/", var, "/Rasters"),
full.names = TRUE,
pattern = glob2rx(paste0(var, "_September_*.tif$")))) %>%
crop(vect(SA)) %>% mask(vect(SA)) %>% mean()
assign(var, c(June, July, August, September)) %>%
set.names(c(paste0(var, "_June"),
paste0(var, "_July"),
paste0(var, "_August"),
paste0(var, "_September")))
}
## Combining all rasters (these are my attempts that fail either completely or change
## layer names to match only the variable name)...
bioclim <- c(clim.vars)
bioclim <- rast(mget(clim.vars))
bioclim <- c(as.name(clim.vars))
bioclim <- c(lapply(clim.vars, as.name))
bioclim <- rast(lapply(clim.vars, as.name))
## This way gets what I want...
# `clim.rast` is defined alongside `clim.vars` at the beginning of my script
clim.rast <- c(max_Tmean, mean_RH, min_RH, mean_Tmax)
# `bioclim` is defined after running the loop above
bioclim <- clim.rast
CodePudding user response:
In situations like this you should use lists. Avoid use assign
and get
.
It is difficult to answer your question as your code is not self-contained (there is no data), but it could look like this:
clim.vars <- c("max_Tmean", "mean_RH", "min_RH", "mean_Tmax")
mnts <- c("_June", "_July", "_August", "_September")
SA <- vect(SA)
x <- list()
for(i in 1:length(clim.vars)) {
ff <- list.files(paste0("./Data/", clim.vars[i], "/Rasters"), full.names = TRUE)
m <- list()
for (j in 1:length(mnts)) {
m[[j]] <- rast(grep(mnts[j], ff)) |> crop(SA) |> mean() |> mask(SA)
}
names(m) <- paste0(clim.vars[i], mnts)
x[[i]] <- rast(m)
}
z <- rast(x)