# Calculating areas of different raster classes in R?

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?

• 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
• 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:

``````library(dplyr)
library(raster)

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

as.data.frame(r) %>%
group_by(layer) %>%
tally() %>%
mutate(area = n * res(r) * res(r))
``````
``````# 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.

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