I have generated a raster as a *.tiff file in R, with four classes. I'd like to calculate the area occupied by each raster class. Each class has a value (-5, -4, -3, -2) - I expect that I could also count the number of pixels in each raster class and multiply it with the cell size (0.23, I believe).

How can I calculate the area per class?

  • 1
    Is your raster projected or lat-long? Because if lat-long then your cells will be different areas... – Spacedman Feb 23 '17 at 15:03

Even if your raster is lat-long and therefore varying cell area, you can do this in R by adding the areas that correspond to cells with your values using the base tapply function:

First set up some dummy data:

> r = raster()
> r[] = sample(-5:-2, ncell(r), replace=TRUE)

Then do this:

> tapply(area(r), r[], sum)
       -5        -4        -3        -2 
126376977 126301228 125943687 129736879 

area(r) creates a raster where each cell has its area as its value. tapply then sums this over areas grouped by the value in r.

  • This is great, but in what units are the results expressed? square meters? – Jackk Mar 11 at 10:45
  • 1
    For projected coordinate systems its the square units of the projection - square metres or square feet or whatever. For unprojected coordinate systems (eg lat-long, where the cell surface area varies) its square metres as computed by the raster::area function. – Spacedman Mar 11 at 11:52
  • Great, so I guess the raster::area function yields an approximation of metric area based on lat-lon. Do you reccomend reprojecting the raster to a metric CRS for greater accuracy? – Jackk Mar 11 at 13:18
  • That's a potential new question - depends on a lot of things. – Spacedman Mar 11 at 14:31
  • There is an error message when I use it on a UTM raster: "This function is only useful for Raster* objects with a longitude/latitude coordinates". Values differ strongly from the answer @Christopher gave. – Jens Mar 13 at 16:12

Here's another option that should work. Replace -5 with the value for each class. It determines the number of pixels in each class and then multiplies that by the area of each pixel (i.e., the resolution squared).

vals <- getValues(myraster) length(subset(vals, vals == -5)) * res(myraster)^2


This can be done using dplyr with something like the following:


r = raster()
r[] = sample(-5:-2, ncell(r), replace=TRUE)

as.data.frame(r) %>%
  group_by(layer) %>%
  tally() %>%
  mutate(area = n * res(r)[1] * res(r)[2])
# A tibble: 4 x 3
  layer     n  area
  <int> <int> <dbl>
1    -5 16260 16260
2    -4 16285 16285
3    -3 16203 16203
4    -2 16052 16052

You can also just get at the cell frequencies and proportions. If in a projected coordinate system then you can get the class areas by multiplying resolution by cell counts.

r <- raster(matrix(round(runif(25*25, 1, 4)),25,25))
  ( f <- freq(r) )
    ( p <- data.frame(f, p=f[,2] / sum(f[,2])) )

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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