Масштабировать растровую ячейку в стеке от -1 до 1 р - PullRequest
0 голосов
/ 11 сентября 2018

У меня есть растровый стек с 364 слоями с ежедневной скоростью изменения значений NDVI.

Я хочу масштабировать эти значения в каждой ячейке, если положительное значение от 0 до 1 и отрицательное от -1 до 0До сих пор я нашел решение, которое масштабирует значения в отдельных слоях (см. Здесь: Замените конкретное значение в каждой полосе растрового кирпича в 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()
}
}

Я не совсем уверен, дает ли это желаемый результат.Любая помощь очень ценится!

1 Ответ

0 голосов
/ 12 сентября 2018

Некоторые примеры данных

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 для других типов масштабирования.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...