在光栅堆栈的各层之间同步NA

时间:2014-05-28 11:06:58

标签: r raster

我正在尝试开发一个功能,以便在光栅堆栈的各层之间“同步”NAs,即为了确保对于堆栈的任何给定像素,如果一个层具有NA,则所有层应设置为NA对于那个像素。

当将来自不同来源的光栅组合用于物种分布建模时,这尤其有用,因为某些模型无法正确处理NA。

我找到了两种方法,但我发现它们都不令人满意。其中一个需要使用函数getValues,因此不适用于非常大的堆栈或具有低RAM的计算机。另一个更安全,但速度慢得多。因此,我在这里询问是否有人有想法改善我的尝试?

以下是两种可能性:

  1. 使用getValues()

    syncNA1 <- function (x) 
    {
      val <- getValues(x)
      NA.pos <- unique(which(is.na(val), arr.ind = T)[, 1])
      val[NA.pos, ] <- NA
      x <- setValues(x, val)
      return(x)
    }
    
  2. 使用calc()

    syncNA2 <- function(y)
    {
      calc(y, na.rm = T, fun = function(x, na.rm = na.rm)
      {
        if(any(is.na(x)))
        {
          rep(NA, length(x))
        } else
        {
          x
        }
      })
    }
    
  3. 现在演示相同堆栈的各自计算时间:

    > system.time(
    + b1 <- syncNA1(a1)
    + )
       user  system elapsed 
       3.04    0.15    3.20 
    > system.time(
    + b2 <- syncNA2(a1)
    + )
       user  system elapsed 
       5.89    0.19    6.08 
    

    非常感谢你的帮助,

    鲍里斯

3 个答案:

答案 0 :(得分:3)

我不知道速度,但您可能会尝试转换为数组,加载NA并转换回来。伪代码:

xarray<-as.array(xstack)
ind.na<-which(is.na(xarray),array.ind=TRUE)
for(j in nrow(ind.na) ) {
    xarray[ind.na[j,1],ind.na[j,2],]<-NA
   }
nastack<-raster(xarray)

我还没有在那里验证索引的正确选择,也没有验证我是否正确转换回raster stack,但我希望你明白这一点。

编辑:我进行了一次时间测试,栅格为1000x1000,但Josh创建了其他栅格。

 microbenchmark(josh(s),syncNA1(s),syncNA2(s),times=5)
Unit: milliseconds
       expr       min        lq    median        uq        max
    josh(s)  774.2363  789.1653  800.2511  806.5364   809.9087
 syncNA1(s)  652.3928  659.8327  692.3578  695.8057   743.9123
 syncNA2(s) 7951.3918 8291.7917 8604.2226 8606.3432 10254.4739
 neval
     5
     5
     5

答案 1 :(得分:3)

使用名为&#34; s&#34;的堆栈,我将首先使用calc(s, fun = sum)计算一个掩码层,该掩码层记录NA值至少为1的所有单元格的位置堆栈的层次。然后mask()允许您将该掩码应用于堆栈中的每个层。

以下是一个例子:

library(raster)

## Construct reproducible data! (Here a raster stack with NA values in each layer) 
m <- raster(ncol=10, nrow=10)
n <- raster(ncol=10, nrow=10)
m[] <- runif(ncell(m))
n[] <- runif(ncell(n)) * 10
m[m < 0.5] <- NA
n[n < 5] <- NA
s <- stack(m,n)

## Synchronize the NA values
s2 <- mask(s, calc(s,fun = sum))

## Check that it worked
plot(s2)

enter image description here

答案 2 :(得分:1)

我最终在syncNA1和Josh的解决方案之间建立了混合功能。 如果计算机没有足够的RAM,此功能对内存安全,但如果计算机有足够的RAM,则可以更快地处理:

synchroniseNA <- function(x)
{
  if(canProcessInMemory(x, n = 2))
  {
    val <- getValues(x)
    NA.pos <- unique(which(is.na(val), arr.ind = T)[, 1])
    val[NA.pos, ] <- NA
    x <- setValues(x, val)
    return(x)
  } else
  {
    x <- mask(x, calc(x, fun = sum))
    return(x)
  }
}

但是,我凭经验确定data.frame使用的ram数量是光栅文件大小的两倍(n canProcessInMemory()参数,但我不是确切地说我就在这里。

相关问题