在保留日期的情况下在某些 window 内移动均值,R
Moving mean within certain window while preserving Date, R
我有一个 50 层的大型栅格堆栈,我想计算移动 window 10 的平均值和最大值。例如,我想要的是计算层的平均值 1:10和 11:20 等等(所以总共有 5 个平均栅格)。同时,我想根据我使用的函数保留图层的日期(例如,具有最大值或平均日期的栅格日期)。
到目前为止我已经尝试了以下但速度很慢。
谁能帮助我更有效地做到这一点?
考虑将 s_all
作为我的栅格堆栈:
for(i in 1:5){
t[[i]]<-calc(
s_all[[((i-1)*10 + 1):((i-1)*10 + 10)]],
fun = mean, na.rm = T)
t@z$Date[[i]]<-mean.Date(as.Date(
c(s_all@z$Date[[((i-1)*10 + 1)]],
s_all@z$Date[[((i-1)*10 + 10)]])))
}
编辑
示例数据
r <- raster(ncol=10, nrow=10, vals=1:100)
s_all <- stack(replicate(50, r))
d<-sample(seq(as.Date('1999/01/01'), as.Date('2000/01/01'), by="day"), 50)
s_all<-setZ(s_all,d[],"Date")
你说你想要一个 "moving average",但这不是你所描述的(移动平均值将 return 相同的层数,具有局部平滑值)。您所描述的是层的聚合,步长为 10。您可以使用 stackApply
或 aggregate
.
获得它
我更改了您的示例数据以使其值有所不同,并且我没有随机化日期。
library(raster)
r <- raster(ncol=10, nrow=10)
s <- stack(lapply(1:50, function(i) setValues(r, i)))
d <- seq(as.Date('1999/01/01'), as.Date('2000/01/01'), by="day")[1:50]
s <- setZ(s, d, "Date")
对于stackApply
你需要一个索引:
idx <- rep(1:5, each=10)
ss <- stackApply(s, idx, mean)
鉴于聚合层数不变,也可以使用aggregate
sss <- aggregate(s, c(1,1,10), mean)
现在,设置一个新的日期,这里我使用最大值。
newd <- tapply(getZ(s), idx, max)
newd <- as.Date(newd, origin="1970-01-01")
ss <- setZ(ss, newd, "Date")
ss
#class : RasterBrick
#dimensions : 10, 10, 100, 5 (nrow, ncol, ncell, nlayers)
#resolution : 36, 18 (x, y)
#extent : -180, 180, -90, 90 (xmin, xmax, ymin, ymax)
#crs : +proj=longlat +datum=WGS84 +ellps=WGS84 +towgs84=0,0,0
#source : memory
#names : index_1, index_2, index_3, index_4, index_5
#min values : 5.5, 15.5, 25.5, 35.5, 45.5
#max values : 5.5, 15.5, 25.5, 35.5, 45.5
#Date : 1999-01-10, 1999-01-20, 1999-01-30, 1999-02-09, 1999-02-19
我有一个 50 层的大型栅格堆栈,我想计算移动 window 10 的平均值和最大值。例如,我想要的是计算层的平均值 1:10和 11:20 等等(所以总共有 5 个平均栅格)。同时,我想根据我使用的函数保留图层的日期(例如,具有最大值或平均日期的栅格日期)。
到目前为止我已经尝试了以下但速度很慢。 谁能帮助我更有效地做到这一点?
考虑将 s_all
作为我的栅格堆栈:
for(i in 1:5){
t[[i]]<-calc(
s_all[[((i-1)*10 + 1):((i-1)*10 + 10)]],
fun = mean, na.rm = T)
t@z$Date[[i]]<-mean.Date(as.Date(
c(s_all@z$Date[[((i-1)*10 + 1)]],
s_all@z$Date[[((i-1)*10 + 10)]])))
}
编辑 示例数据
r <- raster(ncol=10, nrow=10, vals=1:100)
s_all <- stack(replicate(50, r))
d<-sample(seq(as.Date('1999/01/01'), as.Date('2000/01/01'), by="day"), 50)
s_all<-setZ(s_all,d[],"Date")
你说你想要一个 "moving average",但这不是你所描述的(移动平均值将 return 相同的层数,具有局部平滑值)。您所描述的是层的聚合,步长为 10。您可以使用 stackApply
或 aggregate
.
我更改了您的示例数据以使其值有所不同,并且我没有随机化日期。
library(raster)
r <- raster(ncol=10, nrow=10)
s <- stack(lapply(1:50, function(i) setValues(r, i)))
d <- seq(as.Date('1999/01/01'), as.Date('2000/01/01'), by="day")[1:50]
s <- setZ(s, d, "Date")
对于stackApply
你需要一个索引:
idx <- rep(1:5, each=10)
ss <- stackApply(s, idx, mean)
鉴于聚合层数不变,也可以使用aggregate
sss <- aggregate(s, c(1,1,10), mean)
现在,设置一个新的日期,这里我使用最大值。
newd <- tapply(getZ(s), idx, max)
newd <- as.Date(newd, origin="1970-01-01")
ss <- setZ(ss, newd, "Date")
ss
#class : RasterBrick
#dimensions : 10, 10, 100, 5 (nrow, ncol, ncell, nlayers)
#resolution : 36, 18 (x, y)
#extent : -180, 180, -90, 90 (xmin, xmax, ymin, ymax)
#crs : +proj=longlat +datum=WGS84 +ellps=WGS84 +towgs84=0,0,0
#source : memory
#names : index_1, index_2, index_3, index_4, index_5
#min values : 5.5, 15.5, 25.5, 35.5, 45.5
#max values : 5.5, 15.5, 25.5, 35.5, 45.5
#Date : 1999-01-10, 1999-01-20, 1999-01-30, 1999-02-09, 1999-02-19