0

I would like to calculate the percentage of a class (for example forest) in a classified raster image inside a buffer (for example 1000m).

Speciffically, I have a 30x30m classified raster and for each pixel I'd like to know the percentage of forest in a buffer of 1000m for the entire image. The result should be a raster where each pixel has the percentage of the class in that buffer.

I think one way could be using "window_lsm" from the package "landscapemetrics", but I'm not sure.

2
  • By "buffer" do you mean in a radius of 1000m of each pixel? A moving window calculation? See ?focal in the raster (or maybe terra) package.
    – Spacedman
    Commented Sep 2, 2021 at 18:32
  • Yes, in a radius of 1000m of each pixel. And, yes a moving window. I'll see this function. Thanks. Commented Sep 2, 2021 at 19:14

1 Answer 1

2

The landscapemetrics::window_lsm is very slow. You would be better served just using a focal function in raster or terra. Here is an example in terra, you can read in your raster using terra::rast.

Add package and create an example 4 class raster.

library(terra)
r <- rast(nrow=1000, ncol=1000)
  r[] <- sample(1:4, ncell(r), replace=TRUE)

Write a function that returns percent of class(s). We set the default to 2,3 as to illustrate that there may be more than one class of interest (eg., 2 forest classes). You can simply change the default value(s) to suit your data.

pclass <- function(x, y=c(2,3)) {
  return( length(which(x %in% y)) / length(x) )
}

Now, we pass our pclass function to the focal function thus, returning class percent within a 9x9 window.

( pf <- terra::focal(r, w=matrix(1, 9, 9), pclass) )

par(mfrow=c(2,1))
  plot(r)
  plot(pf)

If your raster is projected and you want a circular focal window you can use the focalMat function to create an appropriate matrix (in this example 90m radius). The one catch is that the function returns weights, which can be dealt with by replacing non-zero values with 1 (as shown). This matrix would then be passed to the w argument in terra::focal.

f <- terra::focalMat(r, 90, "circle") 
  f[f > 0] <- 1
2
  • Thanks you so much Jeffrey Evans for helm me. I tried with my raster and it seems that worked. Just one more question: In the case of the matrix (1,9,9) means the function will use nine pixels of 30m resolution in my case? It seems that the second option using "f" is more apropriate to me, because my raster is in a projected coordinate system and I'd like to use a circular buffer. Thanks again. Commented Sep 3, 2021 at 17:27
  • @FernandoCésar A rectangular focal window representing 9x9 cells (n=81) would be defined using matrix (1,9,9), If you want a circular window, you still need a matrix but, the focalMat function can facilitate this. You can see what is happening by printing the object after you create it. In the case of a circular window, the values representing "outside the window" are coded as zero. Commented Sep 3, 2021 at 19:14

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.