[英]Efficient way to interpolate time series of raster bricks in R
我有一些代表時間序列的大型柵格塊(每一層都是一個時間點)。 我希望通過在圖層之間進行插值來提高時間分辨率(在下面的示例中,插值使用zoo::na.spline
,盡管我願意接受其他插值方法的幫助)。 我不能在磚頭上直接使用na.spline
它不是為此而設計的,而只是Error in as.array.default(X) : 'dimnames' applied to non-array
給出Error in as.array.default(X) : 'dimnames' applied to non-array
。
目前,我正在使用一系列循環來執行此操作(一個循環生成具有更多時間層的積木,第二個循環將原始積木插入到該層的正確層中,第三個循環使用na.spline每個單元格)。 但是,這對於大型磚塊而言實在是太慢了,而且似乎是一種無效的方法。
一個最小的可復制示例。
首先讓我們制作一個表示低時間分辨率數據的初始柵格磚。 請注意,左上方的單元格始終是NA,因為對於僅包含NA的單元格,任何解決方案都必須健壯:
library(raster); library(rasterVis); library(zoo)
r1 = raster(matrix(c(NA, rep(1,8)), 3, 3))
r2 = raster(matrix(c(NA, rep(2,8)), 3, 3))
r3 = raster(matrix(c(NA, rep(3,8)), 3, 3))
b1 = brick(list(r1,r2,r3))
levelplot(b1)
現在,讓我們創建一個空的柵格磚,在其中插入值:
b2 = brick(lapply(1:9, function(x) raster(matrix(NA, 3, 3))))
接下來,我們將b1
的層插入適當的b2
層。 請注意,我什至在這里求助於循環,因為將選定圖層分配給柵格磚不起作用 。
old.layers = c(1,4,7)
for (i in 1:nlayers(b1)) {
b2[[old.layers[i]]] = b1[[i]]
}
levelplot(b2, layout=c(9,1))
最后,我們遍歷每個像元進行時間序列插值,然后將結果插入回b2
:
for (cell in 1:ncell(b2)) {
if (all(is.na(as.vector(b2[cell])))) {
# na.spline wil fail if all are NA
new.values = as.numeric(rep(NA, dim(b2)[3]))
} else {
new.values = na.spline(as.vector(b2[cell]), na.rm = F)
}
b2[cell][] = new.values
}
levelplot(b2, layout=c(9,1))
這是可行的,但似乎效率極低且不夠優雅。 有沒有更快(最好也是更優雅)的方式來做到這一點?
您可以將raster::calc
與以下函數配合使用:
yy <- rep(NA, 9)
fun <- function(y) {
if (all(is.na(y))) yy else na.spline((yy[c(1,4,7)] <- y), xout=1:9)
}
b2 <- calc(b1, fun)
作為參考, raster::approxNA
接近您想要的(但它不添加圖層,並且使用線性插值)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.