downsample/aggregate R rasters with custom function 如何生成多个输出栅格?

How to downsample/aggregate R rasters with custom function to produce multiple output rasters?

我有一个相当复杂的函数,用于计算栅格单元的聚合(下采样)。在这个函数中,我区分了多个案例,案例决定了使用哪个汇总函数。作为一个简化的示例(假设 4277123 是依赖于 vec 的动态计算值):

my_fun <- function(vec, na.rm=TRUE, VERBOSE = FALSE){
  if(max(vec) > 1){
    print("case 1")
    return(42)
  } else if(max(vec) > 2){
    print("case 2")
    return(123)
  } else {
    print("case 3")
    return(77)
  }
}

vhm_2 = raster::aggregate(vhm, 20, fun=my_fun, expand=TRUE, na.rm=FALSE)

这将产生一个具有值 4277123 的栅格。 除此之外,我想要第二个光栅,指示使用了哪种情况,即每个单元格包含数字 1-3 的光栅语句。

当然我可以 运行 两次,第二个函数只是 return 案例编号(而不是“计算”),但是我正在处理大型栅格和计算(用于确定大小写以及实际值)首先是昂贵的,所以我很想避免这种情况。

doc 明确表示 fun 需要 return 一个数字,所以我希望我可以简单地 return 两个案例编号和计算值都破灭了.是否有另一种(计算效率高的)方法来使用自定义函数聚合栅格,我可以获得两个栅格作为输出? https://www.rdocumentation.org/packages/raster/versions/3.5-11/topics/aggregate

您现在可以使用 terra 1.5.15(目前是开发版。您可以使用 install.packages('terra', repos='https://rspatial.r-universe.dev')

安装它
library(terra)
#terra 1.5.15
r <- rast()
set.seed(1)
values(r) <- sample(100, ncell(r), replace=TRUE)
a <- aggregate(r, 10, range)
a
#class       : SpatRaster 
#dimensions  : 18, 36, 2  (nrow, ncol, nlyr)
#resolution  : 10, 10  (x, y)
#extent      : -180, 180, -90, 90  (xmin, xmax, ymin, ymax)
#coord. ref. : lon/lat WGS 84 
#source      : memory 
#names       : lyr.1, lyr.2 
#min values  :     1,    95 
#max values  :     7,   100 

或使用自定义函数

a_fun <- function(v){
  m <- max(v)
  if(m < 80){
    c(1,42)
  } else if(m < 95){
    c(2,123)
  } else {
    c(3, 77)
  }
}

a <- aggregate(r, 5, fun=a_fun)
a
#class       : SpatRaster 
#dimensions  : 36, 72, 2  (nrow, ncol, nlyr)
#resolution  : 5, 5  (x, y)
#extent      : -180, 180, -90, 90  (xmin, xmax, ymin, ymax)
#coord. ref. : lon/lat WGS 84 
#source      : memory 
#names       : lyr.1, lyr.2 
#min values  :     1,    42 
#max values  :     3,   123 

但在这种情况下,您也可以选择这样做:

a_fun <- function(v){
  m <- max(v)
  if(m < 80){
    1
  } else if(m < 95){
    2
  } else {
    3
  }
}

a <- aggregate(r, 5, fun=a_fun)
b <- classify(a, matrix(c(1,42, 2,123, 3, 77), ncol=2, byrow=TRUE))