How to iterate through directories to process raster files without a loop with the apply family in R
How to iterate through directories to process raster files without a loop with the apply family in R
I have raster files (.tif) inside different folders (those are my models). I need to import them into individual objects and process them for creating an array (I'll use "abind" for that).
I do have a large number of models thus creating a huge array dataset. I've manage to create a function for reading and processing the models at once. The catch is that maybe is not such a good idea growing an array inside a for loop due to the complexity of the dataset, which could incore in some error.
How to build a function for that making use of the apply R's family functions?
Here is the function I've made
require(raster)
require(abind)
require(rgdal)
myFunction <- function (x)
{
directories <- list.dirs( x, full.names = TRUE)[-1]
e <- extent(xmin, xmax, ymin, ymax)
rcp <- NULL
for (i in 1:length(directories))
{
models_raw <- stack(list.files(directories[i],pattern = ".tif$", full.names = TRUE))
models_e <- crop( models_raw , e )
val <- values (models_e)
coord <- xyFromCell(models_e, 1:ncell(models_e))
models <- cbind(coord, val)
models <- na.omit(models)
rcp <- abind (rcp, models, along = 3)
}
return(rcp)
}
scenario <- myFunction( x = ".//data//models//")
1 Answer
1
Simply generalize your processing into a defined function with directory as a parameter, all to be called with lapply. At the end use a do.call to combine all models. There is no need for individual objects.
lapply
do.call
model_process <- function(dir) {
model <- stack(list.files(dir, pattern = ".tif$", full.names = TRUE))
e <- extent(xmin, xmax, ymin, ymax)
model_e <- crop(model, e)
model_val <- getValues(model_e)
coord_model <- xyFromCell(model_e, 1:ncell(model_e))
model_final <- cbind(coord_model, model_val)
model_final <- na.omit(model_final)
return(model_final)
}
directories <- list.dirs(".//data//models//", full.names = TRUE)[-1]
model_list <- lapply(directories, model_process)
scenario <- do.call(abind, c(model_list, along=3))
# ALTERNATIVELY:
apn <- function(...) abind(..., along=3)
scenario <- do.call("apn", model_list)
model_final <- rasterToPoints(model_e)
Even better @RobertHijmans if it works for OP. I am not famaliar with package or raster objects, so I defer to you practitioners.
– Parfait
Jul 2 at 1:30
Hi there @Parfait, your solution worked partially, Since my models are in subfolders of the directory .//data//models// I had to exclude it by adding [-1] in the directories line. But my problem is that in "scenario" my final result objected must have 3 layers. The function abind make this this with along = 3 . How to proper incorporate it there?
– Milton Alves
Jul 2 at 18:20
@MiltonAlves ... use the args argument of
do.call. See edit.– Parfait
Jul 2 at 18:23
do.call
@Parfait I've tried this. Keep getting: Error in if (quote) args <- lapply (args, enquote): argument is not interpretable as logical In addition: Warning message: In if (quote) args <- lapply (args, enquote): the condition has length> 1 and only the first element will be used >
– Milton Alves
Jul 2 at 18:33
By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.
Further simplification is possible with
model_final <- rasterToPoints(model_e)– Robert Hijmans
Jul 1 at 23:20