我正在尝试开发一个功能,以便在光栅堆栈的各层之间“同步”NAs,即为了确保对于堆栈的任何给定像素,如果一个层具有NA,则所有层应设置为NA对于那个像素。
当将来自不同来源的光栅组合用于物种分布建模时,这尤其有用,因为某些模型无法正确处理NA。
我找到了两种方法,但我发现它们都不令人满意。其中一个需要使用函数getValues
,因此不适用于非常大的堆栈或具有低RAM的计算机。另一个更安全,但速度慢得多。因此,我在这里询问是否有人有想法改善我的尝试?
以下是两种可能性:
使用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)
}
使用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
}
})
}
现在演示相同堆栈的各自计算时间:
> 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
非常感谢你的帮助,
鲍里斯
答案 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
,但我希望你明白这一点。
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)
答案 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()
参数,但我不是确切地说我就在这里。