Amrie Singh
Amrie Singh

Reputation: 3

R loop to perform the same task on multiple Rasters?

I am looking to create a loop to perform the same task on 12 raster's in a folder, I've done the said task for 1 raster. The task involves counting the cell (that have either a class of 1 2 3 or 4) and then calculating the area of each class. Then I need to save the area values in a new data frame for further analysis and visualisation.

I need 1 raster saved as baseline (which is the one in my example) and the rest title Sub_A, Sub_B and so on till Sub_K.

library(sp)
library(raster)
library(rgdal)
library(leaflet)

wd<- ('E:/Subs')
setwd(wd)


zuk1<- raster("E:/Subs/ZUK1_MAX.tif")
zuk1
zuk1<- setMinMax(zuk1)
zuk1[zuk1 == 0]<- NA

plot(zuk1, main='Baseline Hazard')

#count for pixel per class
hazard_fr<- freq(zuk1, useNA="no")
hazard_fr
resclass<- res(zuk1)
area_km2<- hazard_fr[,"count"] * prod(resclass) * 1e-06
df_class_area<- data.frame(Hazard = (c("Low", "Moderate", "Significant", "Extreme")))
df_class_area

Upvotes: 0

Views: 649

Answers (2)

Here is another way of getting the desired output. It is very similar to Jeremy's answer; but using lapply.

# List files which names start with zuk and end with .tif
zuk_files <- list.files(pattern = glob2rx("zuk*.tif"))

# The loop
resuls <- lapply(zuk_files, function(x){
  zuk1 <- raster(x)
  zuk1 <- setMinMax(zuk1)
  zuk1[zuk1 == 0] <- NA
  hazard_fr <- freq(zuk1, useNA="no")
  resclass <- res(zuk1)
  hazard_fr[,"count"] * prod(resclass) * 1e-06
})

Upvotes: 1

Jeremy
Jeremy

Reputation: 876

If you provide a small example data, it will be easier for others to help you. I know that for this case, you may not be able to provide them, as tiff files are generally big in size.

Anyway, you can try this:

# list all tiff files in your directory 
zuk_files <- list.files(pattern = "*.tif")  

# you can also try to be more specific like:
 zuk_files <- list.files(pattern = "ZUK.*_MAX.tif")  

# then apply the same operations for all of the target files

# first create a list for whatever you want to loop over
zuk <- list()
hazard_fr <- list()
resclass <- list()
area_km2 <- list()
df_class_area <- list()

# now do the same things for all items in the list
for (i in 1:length(zuk_files)){
  zuk[[i]] <- raster(zuk_files[[i]])
  zuk[[i]] <- setMinMax(zuk[[i]])
  zuk[[i]][zuk[[i]] == 0] <- NA
  hazard_fr[[i]] <- freq(zuk[[i]],useNA="no")
  resclass[[i]] <- res(zuk[[i]])
  area_km2[[i]] <- hazard_fr[[i]][,"count"] * prod(resclass[[i]]) * 1e-06
  df_class_area[[i]] <- data.frame(Hazard = (c("Low", "Moderate", "Significant", "Extreme")))
}

# then all the data are stored in the list, you can acess them using the index like:
zuk[[1]]

# or save out your target results like:
zuk_1 <- zuk[[1]]

But I am not sure if you have made a mistake in

df_class_area <- data.frame(Hazard = (c("Low", "Moderate", "Significant", "Extreme")))

I am not sure this line does what you expect, anyway, you can learn from the examples above to write the loop for that df_class_area, I believe.

Upvotes: 0

Related Questions