【问题标题】:Avoid a for loop in raster::extract(rst,shp)避免 raster::extract(rst,shp) 中的 for 循环
【发布时间】:2020-10-29 14:38:33
【问题描述】:

我正在使用 R 来提取某些建筑物 3 米缓冲区内栅格的平均值和最大值。

为此,我创建了一个 for 循环,该循环遍历每个建筑物以提取这两个值。我当前的代码如下所示:

for (b in c(1:nrow(buildings_shp))){
    
    building <- buildings_shp[b,]
    
    buffered <- st_buffer(building, 3)
    
    raster_cropped <- crop(raster, extent(buffered))

    mean <- extract(depths_cropped, buffered, fun = mean, na.rm = TRUE)
    max <- extract(depths_cropped, buffered, fun = max, na.rm = TRUE)
    
    buildings_shp[b,"mean"] <- mean
    buildings_shp[b,"max"] <- max
    
  }

然而,这个循环需要相当长的时间(对于 1500 座建筑物,大约需要 17 分钟),而且似乎需要最多时间的步骤是两条提取线。我想知道是否有办法通过以下方式加快这个过程:

a) 避免使用循环——这个循环的原因是我担心如果我在整个数据集上使用 st_buffer,那么当建筑物接近 3 米时,我会生成重叠的几何图形,这可能会导致错误.

b) 并行化 for 循环(我已经尝试过光栅聚类功能,但它并没有加快过程,可能是因为它没有并行化循环本身而是提取函数)

c) 使用 raster::extract 以外的其他功能。我看过一些帖子recommending the velox package,但似乎这个包已经从 CRAN 中删除了。

一些虚拟数据(从上面引用的问题中复制)

library(raster)
library(sf)

raster <- raster(ncol=1000, nrow=1000, xmn=2001476, xmx=11519096, ymn=9087279, ymx=17080719)
raster []=rtruncnorm(n=ncell(raster ),a=0, b=10, mean=5, sd=2)
crs(raster ) <- "+proj=utm +zone=51 ellps=WGS84"
    
x1 <- runif(100,2001476,11519096)
y1 <- runif(100, 9087279,17080719)

buildings_shp <- st_buffer(st_sfc(st_point(c(x1[1],y1[1]), dim="XY"),crs=32651),200000)

【问题讨论】:

  • 嗨@PolyGeo - 有什么建议吗?执行此交叉发布以覆盖两个社区 - 用于编程和代码效率的编码 / R 用户,以及用于空间显式问题的 GIS 用户。我可以删除其中一个问题或将链接添加到问题本身。
  • 我的主要建议是以后不要交叉发布 - 请参阅meta.stackexchange.com/a/64069/215590 这个交叉帖子对这两个问题都有答案,所以我认为你应该离开它们。如果您之前的交叉帖子在一个站点上有答案,但在其他站点上没有,则删除没有答案的帖子。

标签: r performance raster sf


【解决方案1】:

您不需要循环。来自?raster::extract的示例数据

library(raster)
r <- raster(ncol=36, nrow=18, vals=1:(18*36))
cds1 <- rbind(c(-180,-20), c(-160,5), c(-60, 0), c(-160,-60), c(-180,-20))
cds2 <- rbind(c(80,0), c(100,60), c(120,0), c(120,-55), c(80,0))
buildings <- spPolygons(cds1, cds2)

获取缓冲区并提取。由于您要计算两个统计数据,因此在这种情况下不使用汇总函数会更容易。

b <- buffer(buildings, width=3, dissolve=FALSE)
e <- extract(r, b)

现在计算统计数据

sapply(e, mean, na.rm=TRUE)
#[1] 379.4167 330.0741
sapply(e, max, na.rm=TRUE)
#[1] 507 498

terra 应该会更快

library(terra)
v <- vect(b)
x <- rast(r)
ee <- extract(x, v)

【讨论】:

  • 谢谢罗伯特 - 然而,缓冲整个建筑物层似乎会导致缓冲后的几何图形重叠。当我比较使用循环和不使用循环的结果时,我看到得到的结果是不同的。我现在再次使用您的示例进行了测试(将缓冲区增加到 150),结果现在相似。你认为这不应该是个问题吗?
  • 是的,它们重叠,但这不是问题
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-03-15
  • 2021-05-09
  • 2023-03-27
  • 2012-06-25
  • 2020-03-10
相关资源
最近更新 更多