Antonio Barros

As direções, ao longo de todo o intervalo, foram determinadas empregando o teste de Mann-Kendall (Mann, 1945; Kendall, 1955). Esse teste identifica a existência de uma tendência monótona em uma sequência temporal de uma variável. É um método não paramétrico, ou seja, não assume pressuposições acerca da distribuição subjacente dos dados, e sua medida, fundamentada em ordenação, não é afetada por valores atípicos. Esse método, primordialmente, fornece três tipos de informações.

\[ S = \sum_{i=1}^{n-1} \sum_{j=i+1}^{n} \text{sinal}(x_j - x_i) \]

Sendo \(n\) o tamanho da série cronológic; \(x_j\) e \(x_i\) os valores da série cronológica \(x\) nos índices \(i\) e \(j\) dada por:

\[ \text{sinal}(x_j - x_i) = \begin{cases} +1, & \text{se } x_j - x_i > 0 \\ 0, & \text{se } x_j - x_i = 0 \\ -1, & \text{se } x_j - x_i < 0 \end{cases} \]

Kendall (1975) mostrou que S é normalmente distribuída com média E(S) e variância Var(S). A variância de Kendall é calculada como:

\[ Var = \frac{n(n-1)(2n+5) - \sum_{p=1}^{t} \sum_{q=1}^{t}\text{rep}_{pq}(\text{rep}_{pq}^2 - 1)}{18} \] rep\(_{pq}\) representa o número de empates (valores iguais) entre \(x_p\) e \(x_q\).

Se o tamanho da amostra \(n\) é maior que 10, a estatística de teste normal padrão Z\(_s\) é calculada da seguinte forma: \[ Z_s = \begin{cases} \frac{S - 1} {\text{Var}(S)}, & \text{se } S > 0 \\ \frac{S} {\text{Var}(S)}, & \text{se } S = 0 \\ \frac{S + 1} {\text{Var}(S)}, & \text{se } S < 0 \end{cases} \]

Aplicabildiade

As aplicações do Mann-Kendall são muito amplas e podem ser utilizadas para as seguintes áreas:

Considerações

O código inicia carregando os parâmetros necessários, como o número de camadas no conjunto de dados raster, o número total de células, o tamanho da matriz, o sistema de referência de coordenadas (CRS) e a extensão espacial. Em seguida, ele inicializa uma barra de progresso para acompanhar o processo de cálculo.

A matriz do conjunto de dados raster é convertida em uma matriz numérica para facilitar as operações. Em seguida, um loop é iniciado para percorrer cada linha da matriz. Durante o loop, o código verifica se uma determinada linha contém apenas valores ausentes ou menos de quatro valores não ausentes. Nesses casos, o resultado para essa linha é definido como NA.

Caso contrário, o código realiza as etapas de pré-processamento dos dados antes de aplicar o teste de Mann-Kendall. Se a opção de “prewhiten” (pré-branqueamento) estiver ativada, ele calcula a diferença entre os valores consecutivos, remove os valores ausentes, padroniza os dados e, em seguida, aplica o teste de Mann-Kendall. Os resultados do teste, como a estatística tau e o valor p, são armazenados na matriz “empt”. (Abdia et al., 2019, Barros, 2023)

MKraster <- function(rasterstack, type = c("trend", "pval", "both"), prewhiten = FALSE) {
  
  print(paste("Iniciar MKraster:", Sys.time()))
  print("Parâmetros de carregamento")
  
  layers <- nlayers(rasterstack)
  ncell <- ncell(rasterstack)
  ncol <- ncol(rasterstack)
  nrow <- nrow(rasterstack)
  crs <- crs(rasterstack)
  extent <- extent(rasterstack)
  pb <- txtProgressBar(min = 0, max = ncell, initial = 0)
  
  print("Parâmetros de carregamento concluídos")
  mtrx <- as.matrix(rasterstack, ncol = layers)
  empt <- matrix(nrow = ncell, ncol = 2)
  
  print("Initiating loop operation")
  
  if (prewhiten) {
    for (i in 1:length(mtrx[, 1])) {
      if (all(is.na(mtrx[i, ]))) {
        empt[i, 1] <- NA
      } else if (sum(!is.na(mtrx[i, ])) < 4) {
        empt[i, 1] <- NA
      } else {
        x <- as.numeric(mtrx[i, ])
        x <- diff(x) 
        x <- na.omit(x)
        x <- scale(x)
        empt[i, 1] <- as.numeric(MannKendall(x)$tau)
        empt[i, 2] <- as.numeric(MannKendall(x)$sl)
      }
    }
  } else {
    for (i in 1:length(mtrx[, 1])) {
      if (all(is.na(mtrx[i, ]))) {
        empt[i, 1] <- NA
      } else if (sum(!is.na(mtrx[i, ])) < 4) {
        empt[i, 1] <- NA
      } else {
        empt[i, 1] <- as.numeric(MannKendall(as.numeric(mtrx[i, ]))$tau)
        empt[i, 2] <- as.numeric(MannKendall(as.numeric(mtrx[i, ]))$sl)
      }
    }
  }
  
  if (type == "trend") {
    print("Criando raster vazio")
    trend <- raster(nrows = nrow, ncols = ncol, crs = crs)
    extent(trend) <- extent
    print("Preenchendo raster de tendência")
    values(trend) <- empt[, 1]
    print(paste("Terminando o MKraster em", Sys.time()))
    return(trend)
  } else if (type == "pval") {
    pval <- raster(nrows = nrow, ncols = ncol, crs = crs)
    extent(pval) <- extent
    print("Preenchendo raster de significância")
    values(pval) <- empt[, 2]
    print(paste("Terminando o MKraster em", Sys.time()))
    return(pval)
  } else if (type == "both") {
    tr <- raster(nrows = nrow, ncols = ncol, crs = crs)
    pv <- raster(nrows = nrow, ncols = ncol, crs = crs)
    print("Preenchendo conjunto raster")
    values(tr) <- empt[, 1]
    values(pv) <- empt[, 2]
    brk <- brick(tr, pv)
    extent(brk) <- extent
    names(brk) <- c("trend", "p.value")
    print(paste("Terminando o MKraster em", Sys.time()))
    return(brk)
  }
}

Como executar:

# Objeto <- MKraster(TRMM_stack, type = "pval", prewhiten = TRUE)

Testando:

## Carregando pacotes exigidos: sp
# Função
pvalueMK <- MKraster(Conjunto, type = "pval", prewhiten = FALSE)
## [1] "Iniciar MKraster: 2023-05-24 13:53:45.956126"
## [1] "Parâmetros de carregamento"
## [1] "Parâmetros de carregamento concluídos"
## [1] "Initiating loop operation"
## [1] "Preenchendo raster de significância"
## [1] "Terminando o MKraster em 2023-05-24 13:54:13.558075"
# Resultado
plot(pvalueMK)