我有一个包含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()
}
}
我不太确定这是否会产生所需的输出。很感谢任何形式的帮助!
一些示例数据
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
。