【问题标题】:Function to sum each grid cells of raster stack using other rasters as an indicator使用其他栅格作为指标对栅格堆栈的每个网格单元求和的函数
【发布时间】:2018-04-17 05:17:50
【问题描述】:
## input raster
s <- stack(list.files("~/dailyraster", full.names=TRUE)) # daily raster stack
r_start <- raster("~/stackSumSTART.asc") # this raster contain starting Julian day
r_end <- raster("~/stackSumEND.asc") # this raster contain ending Julian day
noNAcells <- which(!is.na(r[])) # cell numbers which contain values

## dummy raster
x <- r
x[] <- NA 

## loop
for (i in noNAcells) {      
  x[i] <- sum(s[[r_start[i]:r_end[i]]][i])
}

我想创建一个类似stackApply() 的函数,但我希望它在单元格的基础上工作。

以上是for()循环版本,效果不错,但耗时太长。

关键是每个单元格从上面脚本中的两个栅格层r_startr_end 中获取sum() 的范围。

现在我正在努力使用apply() family 转换此代码。

有没有可能通过for() 循环提高速度?或者请给我一些提示以在apply()中编写此代码

任何cmets都会帮助我,谢谢。

【问题讨论】:

    标签: r raster


    【解决方案1】:

    你的方法

    x <- s$layer.1
    
    system.time(
    for (i in 1:ncell(x)) {
         x[i] <- sum(s[[r_start[i]:r_end[i]]][i], na.rm = T)
       }
    )
    
       user  system elapsed 
      0.708   0.000   0.710
    

    我的建议

    您可以在堆栈末尾添加用作索引的栅格,然后使用calc 来加快处理速度(~30-50x)。

    s2 <- stack(s, r_start, r_end)
    sum_time <- function(x) {sum(x[x[6]:x[7]], na.rm = T)}
    
    system.time(
       output <- calc(s2, fun = sum_time)
    )
    
       user  system elapsed 
      0.016   0.000   0.015
    
    all.equal(x, output)
    
    [1] TRUE
    

    样本数据

    library(raster)
    
    # Generate rasters of random values
    r1 <- r2 <- r3 <- r4 <- r5 <- r_start <- r_end <- raster(ncol=10, nrow=10)
    
    r1[] <- rnorm(ncell(r1), 1, 0.2)
    r2[] <- rnorm(ncell(r2), 1, 0.2)
    r3[] <- rnorm(ncell(r3), 1, 0.2)
    r4[] <- rnorm(ncell(r4), 1, 0.2)
    r5[] <- rnorm(ncell(r5), 1, 0.2)
    s <- stack(r1,r2,r3,r4,r5)
    
    r_start[] <- sample(1:2, ncell(r_start),replace = T)
    r_end[] <- sample(3:5, ncell(r_end),replace = T)
    

    【讨论】:

    • 非常感谢 DJack!
    • 我有以下问题。我将sum_time() 修改为sum_time2 &lt;- function(x) {sum(x[x[ifelse(nlayers(x)==7, 6, 7)]:x[ifelse(nlayers(x)==7, 7, 8)]], na.rm = T)},但控制台返回错误cannot use this function。当我使用nlayers(s2) 时,除了ifelse() 函数中的nlayers(x)(这有点奇怪),它可以工作。我认为有一些规则可以定义或使用我不知道的函数。
    • 在函数中,x 是一个向量,对应于堆栈中每个栅格的值,用于一个单元格。这意味着您应该使用length(x) 代替nlayers(x)。话虽如此,添加此功能将(略微)降低calc的速度。最好在调用calc之前存储a = nlayers(s2) - 1b = nlayers(s2),并将函数定义为sum(x[x[a]:x[b]]
    猜你喜欢
    • 2013-04-22
    • 1970-01-01
    • 2021-07-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-03-05
    • 1970-01-01
    相关资源
    最近更新 更多