我们可以将spatialEco::hsp函数与terra::app并行使用吗?

lvmkulzt  于 2023-10-13  发布在  其他
关注(0)|答案(1)|浏览(93)

我尝试并行计算分层坡度位置:

library(terra)
library(spatialEco)

r <- rast()
result <- (r, hsp, core=12)

我得到以下错误:
fin(v,...)中的错误:v必须是terra SparRaster类对象
是否有方法并行化任何{spatialEco}函数?

sgtfey8w

sgtfey8w1#

函数spatEco::hsp是用来处理raster*对象的,所以如果你想并行化它,你必须尝试使用clusterR。然而,由于该函数依赖于focal操作,我不知道是否可以并行化它。为了获得一些计算时间,你可以使用hsp的修改版本,编写为使用spatRast

terra_hsp <-
  function (x,
            min.scale = 3,
            max.scale = 27,
            inc = 4,
            win = "rectangle",
            normalize = FALSE)
  {
    scales = rev(seq(from = min.scale, to = max.scale, by = inc))
    for (s in scales) {
      if (win == "circle") {
        if (min.scale < terra::res(x)[1] * 2)
          stop("Minimum resolution is too small for a circular window")
        m <- terra::focalMat(x, s, type = c("circle"))
        m[m > 0] <- 1
      }
      else {
        m <- matrix(1, nrow = s, ncol = s)
      }
      message("Calculating scale:", s, "\n")
      scale.r <- x - terra::focal(x, w = m, fun = mean)
      if (s == max(scales)) {
        scale.r.norm <- 100 * ((
          scale.r - as.numeric(terra::global(
            scale.r,
            stat = "mean", na.rm =
              T
          )) / as.numeric(terra::global(
            scale.r, stat = "sd", na.rm = T
          ))
        ))
      }
      else {
        scale.r.norm <- scale.r.norm + 100 * ((
          scale.r -
            as.numeric(terra::global(
              scale.r, stat = "mean", na.rm = T
            )) / as.numeric(terra::global(
              scale.r,
              stat = "sd", na.rm =
                T
            ))
        ))
      }
    }
    if (normalize == TRUE) {
      scale.r.norm <-
        (scale.r.norm - as.numeric(terra::global(
          scale.r.norm,
          stat = "min", na.rm =
            T
        ))) / (as.numeric(terra::global(
          scale.r.norm,
          stat = "max", na.rm =
            T
        )) - as.numeric(terra::global(
          scale.r.norm,
          stat = "min", na.rm =
            T
        )))
    }
    return(scale.r.norm)
  }

我们来做个基准:

library(terra)
library(raster)
library(spatialEco)
library(microbenchmark)

f <- system.file("ex/elev.tif", package="terra")
r <- terra::rast(f)
p <- raster::raster(f)
microbenchmark(raster=hsp(p),terra=terra_hsp(r),times=10)

Unit: milliseconds
   expr       min       lq      mean    median        uq      max neval cld
 raster 5270.0466 5283.754 5438.2693 5310.7328 5360.2034 6554.091    10   b
  terra  169.9311  171.102  174.4463  174.3601  177.5812  180.184    10  a

terra功能快30倍!!!这已经是一个很好的进步了

相关问题