如何聚合分类 SpatRaster

How to aggregate categorical SpatRaster

我是 terra 包的新手。我正在尝试 aggregate 只有一层的分类栅格(或 SpatRaster,更准确地说)。结果应该是一个栅格,其层数与原始栅格中的类别一样多;单元格的值应包含每个类别中原始(较小)单元格的数量。

这是一个展示我试图实现的目标的示例:

    library(terra)

    # the SpatRaster with 3 categories: 1, 2, 3
    set.seed(0)
    r <- rast(nrows=4, ncols=4)
    values(r) <- sample(3, ncell(r), replace=TRUE)

    # create one layer per category with binary indicators
    r1 <- subst(r, from=c(2,3), 0)
    r2 <- subst(r, from=c(1,3), 0); r2 <- subst(r2, from=2, 1)
    r3 <- subst(r, from=c(1,2), 0); r3 <- subst(r3, from=3, 1)
    
    # stack
    s <- c(r1, r2, r3)
    names(s) <- c("cat1", "cat2", "cat3")
    
    # aggregate
    a <- aggregate(s, fact = 2, fun = "sum")

这适用于此示例。但它既不实用也不高效。对于大型栅格数据集(数量级为 1GB-10GB)和许多类别,这可能(?)不可行。

那么,terra 专业人士会怎么做呢?

这里有一个更精简的方法

您的示例数据:

library(terra)
set.seed(0)
r <- rast(nrows=4, ncols=4)
values(r) <- sample(3, ncell(r), replace=TRUE)

解决方案:

s <- segregate(r)
a <- aggregate(s, 2, sum)

也可以这样做:

b <- list()
for (i in 1:3) {
    b[[i]] <- aggregate(r, 2, function(v) sum(v==i,na.rm=TRUE))
}
b <- rast(b)

你也可以这样写(不推荐)

bb <- lapply(1:3, \(i) aggregate(r, 2, \(v) sum(v==i,na.rm=TRUE))) |>
      rast()