[英]Stack rasters and calculate each pixel's max value then keep that value for rest of the layers in R
我每天堆疊 181 個 ndvi 光柵。 我想為每個像素找到峰值,然后將峰值分配給 rest。原始數據曲線:
這就是我要的:
此結果適用於單個像素。 我已經在 excel 中完成了,但為了方便起見,我想在 R 中創建一個代碼。 現在每個像素在不同的日期達到峰值(因此堆棧中的不同層)。
這是我試過的
fn <- list.files(pn, '*.tif$', full.names = TRUE)
rn <- lapply(fn, raster)
bn <- brick(rn)
for (j in 1:ncell(bn)) {
x <- bn[j]
y <- which.max(x)
x[y:length(x)] <- x[y]
}
現在,如果我在沒有循環的情況下使用它,這段代碼就可以工作了。 錯誤可能是因為某些單元格有 NA。 每層有 24 個單元,只有 14 個有數據。 Rest 被屏蔽了。
對於處理柵格數據,我建議使用terra
package。它是對raster
package 的更新,速度更快,在大多數情況下更易於使用(您可以使用install.packages('terra')
安裝)。 terra
有一組apply
函數,允許您在每個像素堆棧上應用函數。 在下面的示例中,我創建了一個帶有一些虛擬數據的 2x2 像素柵格,並使用terra::app
function 執行您在問題中概述的過程:
# Create random data for 181 rasters.
x = seq(-0, 10, length.out=181)
# `dnorm` can be used to simulate a bell curve, like the NDVI data.
vals = rep(dnorm(x, 5, 1), 4)
# I couldn't get the raster to reshape correctly so I am just taking the first
# 50 values so the data are a nice bell curve.
arr <- array(vals, dim = c(2, 2, 50))
# Replace this with your data. From your code, you can just use:
# bn <- terra::rast(fn)
r <- terra::rast(arr)
# Define a custom function that operates on one stack of pixels at a time.
fill_max <- function(timeseries) {
# Find the index with the max value
idx = which.max(timeseries)
# Set all values past the max to the max value
timeseries[idx:length(timeseries)] <- timeseries[idx]
return(timeseries)
}
# Apply the function to the raster.
out <- terra::app(r, fun=fill_max)
# Check that process worked. Take the timeseries of the first pixel.
vals <- terra::values(out)[1,]
# Plot the timeseries.
plot(1:length(vals), vals)
創建於 2023-01-18,使用reprex v2.0.2
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.