Search code examples
raggregaterasterspatialterra

Understanding aggregate from the {terra} package in R


I don't understand what the R {terra} package is doing regarding aggregating cells of rasters. Here is an example without plotted output.

library("terra")

x <- rast(nrow=5, ncol=4)

values(x) <- c(1,NA,NA,1,
               1,NA,NA,1,
               1,NA,NA,1,
               1,NA,NA,1,
               1,NA,NA,1)

y <- aggregate(x, fact = 2, fun = "length")

y_polys <- as.polygons(y, dissolve = FALSE) %>% 
            st_as_sf() %>%
            rename(values = lyr.1)

ggplot() + geom_sf(data = y_polys, aes(fill = as.character(values)))

Raster plot example

Why are the values of the cells all 4? Shouldn't two of the cells have the value 2 instead of 4, because there were only 2 raster cells which went into the 'length' ? I try to illustrate this point with another picture below:

enter image description here



EDIT 1:

This gives me the desired result, but I'm a bit confused why (and is there a better way?).

library("terra")

x <- rast(nrow=5, ncol=4)

values(x) <- c(1,NA,NA,1,
               1,NA,NA,1,
               1,NA,NA,1,
               1,NA,NA,1,
               1,NA,NA,1)

y <- classify(x, cbind(NA, 0))

z <- aggregate(y, fact = 2, fun = sum, na.rm=T)

z_polys <- as.polygons(z, dissolve = FALSE) %>% 
            st_as_sf() %>%
            rename(values = lyr.1)

ggplot() + geom_sf(data = z_polys, aes(fill = as.character(values)))

Corrected raste

FOLLOW-UP:

Hi Robert,

Thanks for the help. I can see that length counts NAs as per your example.

length(c(NA, NA, 1, 1))
[1] 4

But why in this example below, are the two bottom cells '4', when only 2 raster cells were used for each?

library("terra")
x <- rast(nrow=5, ncol=4)
values(x) <- c(1,NA,NA,1, 1,NA,NA,1, 1,NA,NA,1, 1,NA,NA,1, 1,NA,NA,1)
y <- aggregate(x, fact = 2, fun = length)

plot(y, col=c("pink", "light blue"))
lines(rast(x), col="gray", lwd=3)
lines(y, col="blue", )
text(x)
text(y, cex=1.5, col="red")

rast


Solution

  • I think that you misunderstand how length treats NAs:

    length(c(NA, NA, 1, 1))
    [1] 4
    

    Instead of length, you can use sum

    library("terra")
    x <- rast(nrow=5, ncol=4)
    values(x) <- c(1,NA,NA,1, 1,NA,NA,1, 1,NA,NA,1, 1,NA,NA,1, 1,NA,NA,1)
    y <- aggregate(x, fact = 2, fun = sum, na.rm=TRUE)
    
    plot(y, col=c("pink", "light blue"))
    lines(rast(x), col="gray", lwd=3)
    lines(y, col="blue", )
    text(x)
    text(y, cex=1.5, col="red")
    

    enter image description here

    More generally, if you want to count the number of cells that are not NA you can do

    z <- !is.na(x)
    y <- aggregate(z, fact = 2, fun = sum, na.rm=TRUE)