Home > Enterprise >  Using loops to create objects and then applying a function
Using loops to create objects and then applying a function

Time:11-27

I am trying to shortern my code by using functions and for loops.

For the example below, I would like to create 5 different objects and then apply raster to each object that is created. How can I do this with loops and functions?

#Defining variables of interest
url = "https://files.isric.org/soilgrids/latest/data/" # Path to the webDAV data.
voi1 = "sand"
voi2 = "clay"
voi3 = "silt"
voi4 = "phh2o"
voi5 = "soc"
depth = "5-15cm"

quantile = "mean" # prediction uncertainty quantified by probability distribution. Using mean of distribution
voi_layer1 = paste(paste(paste(url, voi1, "/", voi1, sep=""), depth, quantile, sep="_"), '.vrt', sep="")
voi_layer2 = paste(paste(paste(url, voi2, "/", voi2, sep=""), depth, quantile, sep="_"), '.vrt', sep="")
voi_layer3 = paste(paste(paste(url, voi3, "/", voi3, sep=""), depth, quantile, sep="_"), '.vrt', sep="")
voi_layer4 = paste(paste(paste(url, voi4, "/", voi4, sep=""), depth, quantile, sep="_"), '.vrt', sep="")
voi_layer5 = paste(paste(paste(url, voi5, "/", voi5, sep=""), depth, quantile, sep="_"), '.vrt', sep="")

#Apply 'raster' so can derive descriptions of each layer
sand = raster(voi_layer1)
clay = raster(voi_layer2)
silt = raster(voi_layer3)
ph = raster(voi_layer4)
org_carb = raster(voi_layer5)

CodePudding user response:

There are a few ways your code could be streamlined. Since you're performing the same operation for each VOI, you can store them in a vector. Note that voi here contains all 5 VOI:

base_url <- "https://files.isric.org/soilgrids/latest/data/" # Path to the webDAV data.
voi <- c('sand', 'clay', 'silt', 'phh2o', 'soc')
depth <- "5-15cm"
quantile <- "mean" 

We can use sprintf to more succinctly create the fetch URLs:

urls <- sprintf('%s%s/%s_%s_%s.vrt', base_url, voi, voi, depth, quantile)
names(urls) <- voi
                                                                       sand 
  "https://files.isric.org/soilgrids/latest/data/sand/sand_5-15cm_mean.vrt" 
                                                                       clay 
  "https://files.isric.org/soilgrids/latest/data/clay/clay_5-15cm_mean.vrt" 
                                                                       silt 
  "https://files.isric.org/soilgrids/latest/data/silt/silt_5-15cm_mean.vrt" 
                                                                      phh2o 
"https://files.isric.org/soilgrids/latest/data/phh2o/phh2o_5-15cm_mean.vrt" 
                                                                        soc 
    "https://files.isric.org/soilgrids/latest/data/soc/soc_5-15cm_mean.vrt" 

And finally, we can use lapply to perform the raster() function on each constructed URL (lapply is a looping function).

rasters <- lapply(urls, raster)

Note that because we've provided names for the elements of urls above, these are retained in the rasters result, so you can retrieve individual rasters either with numerical indexing (rasters[1]), or named indexing (rasters['sand']).

CodePudding user response:

In general, you can make a function that creates an object, call it in a for-loop and use assign to assign them variable names. I recommend using glue function from the "glue" package as it is more intuitive than paste. I was not able to get the raster function to work on my computer as I'm getting this error. However, that's the idea.

library(glue)

raster_object <- function(url, voi, depth, quantile){
  return(raster(glue("{url}/{voi}/{voi}_{depth}_{quantile}.vrt")))
}

for (voi in c("sand", "clay")){
  assign(glue("raster_{voi}"),  raster_object(url = "https://files.isric.org/soilgrids/latest/data", voi, depth = "5-15cm", quantile = "mean"))
}

  •  Tags:  
  • r
  • Related