Search code examples
rgeospatialraster

Raster in R: Create Zonal Count of specific cell values without reclassification


I would like to know if there is way to create zonal statistics for RasterLayerObjects, specifically the count of a given cell value (e.g. a land-use class) in R without having to reclassify the whole raster. The solution should be memory efficient in order to work on large raster files i.e. no extraction of the values into a matrix in R is desired.

Below an example of how I handle it until now. In this case I reclassify the original raster to hold only 1 for the value of interest and missings for all other values.

My proposed solution creates both, redundant data and additional processing steps to get me to my initial goal. I thought something like zonal(r1[r1==6],r2,"count") would work but obviously it does not (see below).

# generate reproducible Raster 
library("raster")

## RASTER 1 (e.g. land-use classes)
r1 <- raster( crs="+proj=utm +zone=31")
extent(r1) <- extent(0, 100, 0, 100)
res(r1) <- c(5, 5)
values(r1) <- sample(10, ncell(r1), replace=TRUE)
plot(r1)

## RASTER 2 (containing zones of interest)
r2 <- raster( crs="+proj=utm +zone=31")
extent(r2) <- extent(0, 100, 0, 100)
res(r2) <- c(5, 5)
values(r2) <- c(rep(1,100),rep(2,100),rep(3,100),rep(4,100))
plot(r2)

# (1) ZONAL STATISTICS
# a. how many cells per zone (independent of specific cell value)
zonal(r1,r2,"count")

# b. how many cells per zone of specific value 6
zonal(r1[r1==6],r2,"count")
# -> fails

# with reclassification
r1.reclass<-
  reclassify(r1,
             matrix(c(1,5,NA,
                    5.5,6.5,1, #class of interest 
                    6.5,10,NA),
                    ncol=3,
                    byrow = T),
             include.lowest=T # include the lowest value from the table.
           )
zonal(r1.reclass,r2,"count")

Solution

  • you can use raster::match.

    zonal(match(r1, 6),r2, "count")
    

    As you can see from plot(match(r1, 6)), it only returns raster cells which hold the desired value(s). All other cells are NA.

    r1==6 as used in your try unfortunately returns a vector and therefore cannot be used in focal anymore.