簡體   English   中英

在R中插值柵格磚時間序列的有效方法

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM