R:如何使用并行计算计算栅格趋势
R: How to use parallel computing on calculating trends in raster
最近我在 R spatialEco 中发现了这个库。我想计算 R 中栅格堆栈的 Kendall tau 统计量。但是,这会花费很多时间,因为这个库在计算机上只使用一个核心(我计划使用的栅格在 250 m 的全球范围内分辨率)
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)
这样的库来计算栅格堆栈上的趋势?是不是要把数据转成矩阵再用这些库?
spatialEco::raster.kendall()
调用 raster::overlay()
并且可以 运行 并行:
从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)
}
启动一个有 n
个节点的集群。
beginCluster(n=2)
并行计算。
logo.trend.parallel <- clusterR(r.logo, overlay, args=list(fun=trend.slope))
停止集群。
endCluster()
这里是定时对比。
示例数据(为了避免所有值都相同而更花哨)
library(raster)
f <- system.file("external/rlogo.grd", package="raster")
s <- stack(f)+1
r.logo <- stack(s/2, s, s*2)
我这里只计算 Tau。首先用 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()
没有时间增益,但对于小型数据集来说这是预期的,对于大型数据集可能会有所不同。
最近我在 R spatialEco 中发现了这个库。我想计算 R 中栅格堆栈的 Kendall tau 统计量。但是,这会花费很多时间,因为这个库在计算机上只使用一个核心(我计划使用的栅格在 250 m 的全球范围内分辨率)
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)
这样的库来计算栅格堆栈上的趋势?是不是要把数据转成矩阵再用这些库?
spatialEco::raster.kendall()
调用 raster::overlay()
并且可以 运行 并行:
从
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) }
启动一个有
n
个节点的集群。beginCluster(n=2)
并行计算。
logo.trend.parallel <- clusterR(r.logo, overlay, args=list(fun=trend.slope))
停止集群。
endCluster()
这里是定时对比。
示例数据(为了避免所有值都相同而更花哨)
library(raster)
f <- system.file("external/rlogo.grd", package="raster")
s <- stack(f)+1
r.logo <- stack(s/2, s, s*2)
我这里只计算 Tau。首先用 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()
没有时间增益,但对于小型数据集来说这是预期的,对于大型数据集可能会有所不同。