【问题标题】:How to filter HadISST raster data in a range of months in R?如何在 R 中过滤几个月范围内的 HadISST 栅格数据?
【发布时间】:2017-05-04 11:30:57
【问题描述】:

我正在尝试研究海表温度 (SST) 与特定月份范围内的热带气旋活动的相关性。我使用的数据来自Hadley Centre(NetCDF 格式),使用hadsstR 包中的get_anual_ssts() 函数。

get_annual_ssts <- function(hadsst_raster, years = 1969:2011) {
    mean_rasts <-
        apply(matrix(years), 1, function(x) {
            yearIDx <- which(chron::years(hadsst_raster@z$Date) == x)
            subset_x <- raster::subset(hadsst_raster, yearIDx)
            means <- raster::calc(subset_x, mean, na.rm = TRUE)
            names(means) <- as.character(x)
            return(means)
        })
    mean_brick <- raster::brick(mean_rasts)
    mean_brick <- raster::setZ(mean_brick, as.Date(paste0(years, '-01-01')), 'Date')
    return(mean_brick)
}

我需要一个额外的参数,让我可以按飓风活动的月份进行过滤,而不是计算全年的平均 SST。

例如,对于西南太平洋,我应该可以拨打get_annual_ssts(hadsst_raster, 12:04, 1966:2007),因为12-4月是飓风活动的月份。设置包含两个不同年份的月份范围至关重要(也许说明初始月份和范围长度以简化mean_brick 的结构,保存初始年份的平均值?)。

查看chron 的文档,似乎不可能分配 mm-yy 的子集或类似的东西。 最好的方法是什么?

这是输入栅格数据 (hadsst_raster) 的样子,供参考:

class       : RasterBrick 
dimensions  : 180, 360, 64800, 1766  (nrow, ncol, ncell, nlayers)
resolution  : 1, 1  (x, y)
extent      : -180, 180, -90, 90  (xmin, xmax, ymin, ymax)
coord. ref. : +proj=longlat +datum=WGS84 
data source : ~/Downloads/Hadley/HadISST_sst.nc 
names       : X1870.01.16, X1870.02.14, X1870.03.16, X1870.04.15, X1870.05.16, X1870.06.16, X1870.07.16, X1870.08.16, X1870.09.16, X1870.10.16, X1870.11.16, X1870.12.16, X1871.01.16, X1871.02.15, X1871.03.16, ... 
Date        : 1870-01-16, 2017-02-16 (min, max)
varname     : sst 

以及输出 (get_annual_ssts(hadsst_raster, 1966:2007)) 的样子:

class       : RasterBrick 
dimensions  : 180, 360, 64800, 42  (nrow, ncol, ncell, nlayers)
resolution  : 1, 1  (x, y)
extent      : -180, 180, -90, 90  (xmin, xmax, ymin, ymax)
coord. ref. : +proj=longlat +datum=WGS84 
data source : in memory
names       :      X1966,      X1967,      X1968,      X1969,      X1970,      X1971,      X1972,      X1973,      X1974,      X1975,      X1976,      X1977,      X1978,      X1979,      X1980, ... 
min values  :  -916.8167,  -916.8167,  -916.8167,  -916.8167,  -916.8167,  -916.8167,  -916.8167,  -916.8167,  -916.8167,  -916.8167,  -916.8167,  -916.8167,  -916.8167, -1000.0000, -1000.0000, ... 
max values  :   29.94996,   29.66276,   29.70941,   30.22522,   29.61913,   29.43723,   29.65050,   29.73929,   29.59117,   29.48381,   29.36425,   29.72932,   29.70908,   29.84216,   29.84868, ... 
Date        : 1966-01-01, 2007-01-01 (min, max)

【问题讨论】:

  • 上面的栅格数据是你用return(mean_brick)返回的?
  • 这是输入。对不起,我会区分的。
  • 也许我误解了你,但在我看来,你在输入块中有namesDate 中有关月份的信息。您是否尝试过基于此索引它?
  • @Val 是的,这是真的。我担心在不同年份的月份之间进行过滤。但是那天晚上想起来,我意识到也许这样做的方法是过滤掉我不想要的月份。如果我想出一个合理的方法,我会发布答案。
  • @Val 是的。如果飓风很好并且发生在同一年内,一切都会更容易:P

标签: r r-raster chron


【解决方案1】:

好的,我有一点东西。也许你可以用它来修改你的功能:

## Generate your layer names (used for indexing later)

nms <- expand.grid(paste0('X',1969:2011),c("01","02","03","04","05","06","07","08","09","10","11","12"),'16')

nms <- apply(nms,1,function(x) paste0(x,collapse = '.'))

nms <- sort(nms)

## Generating fake raster brick

r <- raster()
r[] <- runif(ncell(r))

rst <- lapply(1:length(nms),function(x) r)

rst <- do.call(brick,rst)

names(rst) <- nms

现在您可以使用图层名称为砖块编制索引。循环飓风季节(从第 1 年 -1 年开始):

for (ix in 1970:2011){


  sel <- rst[[c(grep(paste0(ix-1,'.12'),nms),sapply(paste0(0,1:4),function(x) grep(paste0(ix,'.',x),nms)))]]


  break ## in case you don't want to go through all iterations

  }

对于第一次迭代,我得到了这个输出:

> sel
class       : RasterStack 
dimensions  : 180, 360, 64800, 5  (nrow, ncol, ncell, nlayers)
resolution  : 1, 1  (x, y)
extent      : -180, 180, -90, 90  (xmin, xmax, ymin, ymax)
coord. ref. : +proj=longlat +datum=WGS84 +ellps=WGS84 +towgs84=0,0,0 
names       :  X1969.12.16,  X1970.01.16,  X1970.02.16,  X1970.03.16,  X1970.04.16 
min values  : 5.988637e-06, 5.988637e-06, 5.988637e-06, 5.988637e-06, 5.988637e-06 
max values  :    0.9999771,    0.9999771,    0.9999771,    0.9999771,    0.9999771 

如果有帮助,请告诉我。


编辑:

所以也许是一个更适用的例子:

(该函数假设您的输入砖层名称x 的格式为Xyyyy.mm.dd

hadSSTmean <- function(x, years, first.range = 11:12, second.range = 1:4){

  nms <- names(x)

  mts <- c("01","02","03","04","05","06","07","08","09","10","11","12")

  xMeans <- vector(length = length(years)-1,mode='list')

  for (ix in 2:length(years){

    xMeans[[ix-1]] <- mean(x[[c(sapply(first.range,function(x) grep(paste0(years[ix-1],'.',mts[x]),nms)),sapply(1:4,function(x) grep(paste0(years[ix],'.',mts[x]),nms)))]])

  }

  return(do.call(brick,xMeans))
  # you could also return the list instead of a single brick
}

【讨论】:

  • 我假设 dts 将是我的原始栅格数据 (hadsst_raster),对吧?
  • 对不起,这将来自我的中间产品......我会更正它。应该是层名nms
  • sel &lt;- 似乎为每次迭代重写(评论break)。如果我错了,请纠正我,但是在循环之前定义 sel &lt;- raster() 然后堆叠到它 (sel &lt;- stack(sel, ... )) 就可以了,对吧?
  • 也许我应该更清楚一点:sel 只是您所在年份的当前选择。这只是一个示例(可以说是概念证明),因此break 声明。您需要在函数中实现索引。我会看看我是否有一些指示。您想选择这些栅格并执行简单的平均吗?
  • 所以first.range 表示上一年的 11 月和 12 月,second.range 表示下一年的 1 月到 4 月?
猜你喜欢
  • 1970-01-01
  • 2020-04-07
  • 1970-01-01
  • 2021-01-17
  • 2020-12-03
  • 2015-10-27
  • 2021-09-06
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多