堆叠中的栅格单元格从-1到1 R.

问题描述 投票:1回答:1

我有一个包含364层的光栅堆栈,每天的NDVI值变化率。

我希望在每个单元格中缩放这些值,如果从0到1为正,如果从-1到0则为负。到目前为止,我只找到了一个在单层中缩放值的解决方案(参见此处:Replace specific value in each band of raster brick in R)而不是沿着多层单元格对象。另外,我在整个时间序列中都有相当数量的带NA的单元格,我也不太确定如何处理这个事实。

我从之前提到的帖子中获取了代码并试图让它解决我的问题:

norm <- function(x){-1+(x-min)*((1-(-1))/(max-min))}

for(j in 1:ncell(tif)){

 if(is.na(sum(tif[j]))){
  NULL
 } else {

 cat(paste("Currently processing layer:", j,"/",ncell(tif), "\n"))

 min <- cellStats(tif[j],'min')
 max <- cellStats(tif[j],'max')

#initialize cluster
#number of cores to use for clusterR function (max recommended: ncores - 1)
beginCluster(31)

#normalize
tif[j] <- clusterR(tif[j], calc, args=list(fun=norm), export=c('min',"max"))

#end cluster
endCluster()
}
}

我不太确定这是否会产生所需的输出。很感谢任何形式的帮助!

r scale raster
1个回答
1
投票

一些示例数据

library(raster)
r <- raster(ncol=10, nrow=10)
s <- stack(lapply(1:5, function(i) setValues(r, runif(100, -1, 1))))
# adding NAs
s[[2]][sample(100, 25, TRUE)] <- NA

对于按单元格(按要求)缩放(或任何其他操作),您可以将calc与对向量一起使用的函数一起使用。例如:

ff <- function(i) {
    p <- which(i >= 0)
    n <- which(i <= 0)
    # positive values
    if (length(p) > 0) {
        i[p] <- i[p] - min(i[p], na.rm=TRUE)
        i[p] <- i[p] / max(i[p])
    }
    # negative values
    if (length(n) > 0) {
        i[n] <- i[n] - max(i[n], na.rm=TRUE)
        i[n] <- i[n] / abs(min(i[n]))
    }
    i
}

测试一下

ff(c(-.3, -.1, .1, .4, .8))
#[1] -1.0000000  0.0000000  0.0000000  0.4285714  1.0000000
ff(c(-.3, -.1, .1, .4, .8, NA))
#[1] -1.0000000  0.0000000  0.0000000  0.4285714  1.0000000         NA
ff(c(-2,-1))
#[1] -1  0
ff(c(NA, NA))
#[1] NA NA

并使用它

z <- calc(s, ff)

请参阅以下内容,根据所有单元格值的最小值和最大值逐层进行缩放(我首先认为这是要求的)。请注意,我在下面使用的函数将值从-1调整为1,但不是最低正值,最高负值为零。

minv <- abs(cellStats(s,'min'))
maxv <- cellStats(s,'max')

f1 <- function(i, mn, mx) {
    j <- i < 0
    j[is.na(j)] <- TRUE
    i[j] <- i[j] / abs(mn)
    i[!j] <- i[!j] / mx
    i
}

ss <- list()
for (i in 1:nlayers(s)) {
    ss[[i]] <- calc(s[[i]], fun=function(x) f1(x, minv[i], maxv[i]))
}

ss1 <- stack(ss)

或者没有循环

f2 <- function(x, mn, mx) {
    x <- t(x)
    i <- which(x > 0)
    i[is.na(i)] <- FALSE
    mxx <- x / mx
    x <- x / mn
    x[i] <- mxx[i]
    t(x)
}

ss2 <- calc(s, fun=function(x) f2(x, minv, maxv))

作为参考,简单地在0和1之间缩放

mnv <- cellStats(s,'min')
mxv <- cellStats(s,'max')
x <- (s - mnv) / (mxv - mnv)

要获得介于-1和1之间的值,您可以执行此操作

y <- 2 * (x - 1)

但是这样以前的负值可以变为正值,反之亦然。

有关其他类型的缩放,请参阅?raster::scale

© www.soinside.com 2019 - 2024. All rights reserved.