# Looping area calculations for multiple rasters in R

The following code works great on individual rasters and gives me the information that I want:

``````r<-rast("LuckSpring_2001.tif")
activeCat(r)<-"Class_name"
r

f <- freq(r)
f\$area <- f\$count * 0.00009
f\$percent = round(100 * f\$area / sum(f\$area), 1)
f
``````

I'm wondering if there is a way to loop this code so I can apply it to multiple rasters and not have to do them all individually. A note that my rasters have different extents and class names.

You can do this by reading the rasters into a list object then iterating through the resulting list, defining a function that operates on each raster.

This creates the list object containing rasters.

``````rasters <- lapply(list.files(getwd(), pattern="tif\$",
full.names=TRUE), rast)
``````

Now, we can operate on the list using lapply as our iterator and bind the results together.

``````results <- lapply(rasters, function(r) {
activeCat(r) <- "Class_name"
f <- freq(r)
f\$area <- f\$count * res(r)
f\$percent <- round(f\$area / sum(f\$area) * 100, 0))
})
( results <- do.call(rbind, results) )
``````
• That's definitely much cleaner than what I came up with! Thanks so much :) Jun 8 at 15:39
• @bigblue5295 Ah, but you did figure it out yourself! List objects are great for acting as "containers". You can then iterate through them using `lapply`. They come in quite handy and have numerous tidy related functions that can operate on them as well. Becoming well versed in using apply-type (`apply`, `tapply`, `lapply`, `mapply`) functions can make things considerably easier, and more efficient, as well. Jun 8 at 17:51

I figured it out! Putting the code that worked for me here in case anybody else wants it.

``````    # Define the list of raster files
raster_files <- list.files(path=("C:/Users/"), pattern='\\.tif\$',
full.names=TRUE)

# Initialize an empty list to store the results
result_list <- list()

# Loop over each raster file
for (file in raster_files) {
r <- rast(file)
# Set the active category to "Class_name"
activeCat(r) <- "Class_name"
# Calculate frequency and area
f <- freq(r)
f\$area <- f\$count * 0.0009 #this number changes depending on resolution
f\$percent <- round(100 * f\$area / sum(f\$area), 1)
result_list[[file]] <- f
}

#List results
for (i in seq_along(result_list)) {
cat("Raster File:", names(result_list)[i], "\n")
print(result_list[[I]])
cat("\n")
}

#This makes a results table
result_table <- bind_rows(result_list, .id = "raster_name")'
``````
• Tip: if you have some functionality that works as a little self-contained "block", write a function that takes parameters and returns the desired output. Then you can test this on single data items and put it in loops for when you have many. It also makes your code more readable. Your entire loop is then something like: `for(file in files){result[[file]] = count_area_percent(file)}` and it makes solutions using `lapply` (see J Evans' answer) neater too. Jun 8 at 6:57