在栅格图层的顺序列表上计算栅格统计信息

时间:2018-06-28 18:35:12

标签: r raster r-raster

假设我有一个rasterstack,由5层组成:

library(raster)
r <- raster(nrows=10,ncols=10)
r[] <- rnorm(100)
stk <- stack(r,r*2,r+10,r-7, r*6)

我想根据不同的数字列表来计算一系列顺序图层的统计信息。

my.seq<-as.numeric(c("2", "1", "2"))

如何计算以下各项的统计信息(例如平均值)

s中的1:2层,即my.seq [1]

s中的第3层,即my.seq [2]

s中的层4:5,即my.seq [3]

我觉得最好使用循环来实现,但是我无法弄清楚它是如何工作的。

任何帮助都会感激不尽。


编辑

这就是我要执行的IRL。我以为我会在这里包括它,以帮助给该问题提供更大的背景。

我正在尝试根据每日温度数据计算每月平均值。我正在使用的栅格堆栈具有数百个图层,每个图层按月依次排列。因此,当1:31层合在一起时,就是1970年1月。在上面的示例中,my.seq是包含每个月中天数的列表。因此,我尝试计算1月31日(一月)和32:60天(二月)等天的平均值。

3 个答案:

答案 0 :(得分:1)

对于您需要不同栅格子集的解释,我不理解您的my.seq示例。这是一个工作示例,其中我使用定义的子集创建列表对象。您所需要做的就是将所需的栅格子集的数字索引传递到堆栈对象的双括号索引。列表对象也必须是使用双括号的子集,因此,它看起来很混乱s[[idx[[i]]]]。但是,如果将其分解,则对于第一个栅格子集,它仅仅是:raster::calc(s[[1:2]], mean)

library(raster)
file <- system.file("external/test.grd", package="raster")
s <- stack(file, file, file)
s <- addLayer(s, raster(file)/2, raster(file)*2)

idx <- list( c(1:2), c(3), c(4:5) )
s.mean <- stack()
  for(i in 1:length(idx)) {
    s.mean <- addLayer(s.mean, calc(s[[idx[[i]]]], mean) )
  }

s.mean
plot(s.mean)

关于扩展问题,您可以在R中使用date类创建索引,并且更加方便的是,rts包允许这些类型的时间序列摘要。

在这里,让我们创建一个包含365层的堆栈,这些堆栈代表一年中的每一天。

library(raster)
f <- raster(nrows=50, ncols=50, xmn=0, xmx=10)
s <- stack()
  for(i in 1:365) {
    x <- f
    x[] <- runif(ncell(x),0,10)
    s <- addLayer(s, x)
}

现在,我们可以创建相应的日期向量。

( d <- seq(as.Date("1970/1/1"), as.Date("1970/12/31"), "days") ) 

可以查询日期向量以提供栅格索引。假设我们想要十二月的平均值,则可以使用which来生成索引。

( dec.idx <- which( months(d) == "December") )
( dec.mean <- calc(s[[dec.idx]], mean) ) 

您可以轻松地创建一个包含每个月的栅格堆栈索引的列表,该列表将等同于您在my.seq对象中描述的内容。

months.idx <- list()   
  for(m in unique( months(d) ) ) {
    months.idx[[m]] <- which( months(d) == m)  
  }  
months.idx

但是,这是内置的功能,可以在rts包中执行这些类型的时间汇总,因此,我们可以通过将堆栈强制为rts对象,然后使用apply函数之一来简化任何for循环。

library(rts)
s.date <- rts::rts(s, d)
( s.month <- apply.monthly(s.date, mean) )

答案 1 :(得分:1)

此函数使用my.seq提取感兴趣的图层(如示例中所示,包括可能重复的图层)。

您可以将它们放入新的stack中,也可以在下面提取它们的代码部分的层级上计算/组合统计信息。

new_stack <- function(x){
  tmp <- stack()
  for(i in x){
    new <- stk[[i]]
    tmp <- stack(tmp, new)  
  }
  return(tmp)
}

tmp2 <- new_stack(my.seq) 

现在,我不确定100%准确地计算平均值,因此我在以下几种方法中做到了:

stack_mean <- function(x){
  tmp         <- stack()
  layer_means <- numeric()

  for(i in x){
    new <- stk[[i]]

    layer_mean <- mean(stk[[i]]@data@values) 
    print(paste("In layer ", i, "the layer mean is ", layer_mean))

    layer_means <- c(layer_means, layer_mean)

    tmp <- stack(tmp, new)  

  }
  print(paste("Mean of means:", mean(layer_means)))
  return(tmp)
}

stack_mean(my.seq)

这将计算几种平均值。首先,分层的手段(我知道不是 您想要的东西-我只是在说明后代):

[1] "In layer  2 the layer mean is  -0.0981706786020096"
[1] "In layer  1 the layer mean is  -0.0490853393010048"
[1] "In layer  2 the layer mean is  -0.0981706786020096"

然后将3层的平均值相加:

[1] "Mean of means: -0.081808898835008"

最后,您有了stack对象的中值,尽管我对此不太了解,也不知道这到底意味着什么,但这显然是一件事情:

mean(tmp2) # equivalently: mean(stack_means(my.seq))

class       : RasterLayer 
dimensions  : 10, 10, 100  (nrow, ncol, ncell)
resolution  : 36, 18  (x, y)
extent      : -180, 180, -90, 90  (xmin, xmax, ymin, ymax)
coord. ref. : +proj=longlat +datum=WGS84 
data source : in memory
names       : layer 
values      : -5.742679, 4.206359  (min, max)

答案 2 :(得分:1)

您可以为此使用stackApply

示例数据

library(raster)
r <- raster(nrows=10, ncols=10, vals=rnorm(100))
stk <- stack(r,r*2,r+10,r-7, r*6)
my.seq <- c(2, 1, 2)

获取索引并使用stackApply

i <- rep(1:length(my.seq), my.seq)
x <- stackApply(stk, i, fun='mean')