Р: Как использовать параллельные вычисления при расчете трендов в растре - PullRequest
1 голос
/ 07 мая 2019

Недавно я наткнулся на эту библиотеку в R atialEco .Я хочу вычислить статистику Тау Кендалла для стека растров в R. Однако это займет много времени, так как эта библиотека использует только одно ядро ​​на компьютере (растр, который я планирую использовать, находится в глобальном масштабе на 250 м.разрешение)

library(raster)
library(spatialEco)

r.logo <- stack(system.file("external/rlogo.grd", package="raster"),
system.file("external/rlogo.grd", package="raster"),
system.file("external/rlogo.grd", package="raster"))

# Calculate trend slope with p-value and confidence level(s)
start_time <- Sys.time()

logo.trend <- raster.kendall(r.logo, tau = TRUE, intercept = TRUE, p.value = TRUE,
z.value = TRUE, confidence = TRUE)

end_time <- Sys.time()
end_time - start_time

names(logo.trend) <- c("slope","tau", "intercept", "p.value", "z.value", "LCI", "UCI")
plot(logo.trend)

Можно ли использовать библиотеку типа library(parallel) для расчета тренда в растровом стеке?Необходимо ли преобразовывать данные в матрицу, а затем использовать эти библиотеки?

Ответы [ 2 ]

2 голосов
/ 10 мая 2019

spatialEco::raster.kendall() вызывает raster::overlay(), и можно запустить это параллельно:

  1. Получить соответствующую функцию от spatialEco::raster.kendall():

    trend.slope <- function(y, p.value.pass = TRUE, z.pass = TRUE, 
                            tau.pass = TRUE, confidence.pass = TRUE, intercept.pass = TRUE) {
        options(warn = -1)
        fit <- EnvStats::kendallTrendTest(y ~ 1)
        fit.results <- fit$estimate[2]
        if (tau.pass == TRUE) {
            fit.results <- c(fit.results, fit$estimate[1])
        }
        if (intercept.pass == TRUE) {
            fit.results <- c(fit.results, fit$estimate[3])
        }
        if (p.value.pass == TRUE) {
            fit.results <- c(fit.results, fit$p.value)
        }
        if (z.pass == TRUE) {
            fit.results <- c(fit.results, fit$statistic)
        }
        if (confidence.pass == TRUE) {
            ci <- unlist(fit$interval["limits"])
            if (length(ci) == 2) {
                fit.results <- c(fit.results, ci)
            }
            else {
                fit.results <- c(fit.results, c(NA, NA))
            }
        }
        options(warn = 0)
        return(fit.results)
    }
    
  2. Запуск кластера с n узлами.

    beginCluster(n=2)
    
  3. Выполнять вычисления параллельно.

    logo.trend.parallel <- clusterR(r.logo, overlay, args=list(fun=trend.slope))
    
  4. Остановить кластер.

    endCluster()
    
1 голос
/ 10 мая 2019

Вот сравнение по времени.

Пример данных (немного сложнее, чтобы все значения не были одинаковыми)

library(raster)
f <- system.file("external/rlogo.grd", package="raster")
s <- stack(f)+1
r.logo <- stack(s/2, s, s*2)

Я только вычисляю Тау здесь. Сначала с raster.kendall

library(spatialEco)
system.time(
 logo.trend1 <- raster.kendall(r.logo, tau=TRUE)
)
#   user  system elapsed 
#   6.73    0.00    6.72 

Теперь с calc и базовой cor функцией

nl <- 1:nlayers(r.logo)
kfun <- function(i) {
 cor(nl, i, method="kendall")
}

system.time(
 logo.trend2 <- calc(r.logo, kfun)
)
#   user  system elapsed 
#   0.51    0.00    0.51 

Это в 13 раз быстрее. Сейчас параллельно

beginCluster(n=4)
system.time(
 logo.trend.parallel <- clusterR(r.logo, calc, args=list(fun=kfun), export="nl")
)
#   user  system elapsed 
#   0.05    0.05    0.69 
endCluster()

Нет выигрыша во времени, но это ожидается для небольшого набора данных и может отличаться от большого набора данных.

...