4

我有一个 netCDF 文件 (.nc),其中包含 16 年(1998 - 2014)的每日降水量(5844 层)。3 个维度是时间(大小 5844)、纬度(大小 19)和经度(大小 20)在 R 中是否有一种直接的方法来计算每个光栅单元:

  • 月平均和年平均
  • 累积比较(例如 1 月至 3 月与所有 1 月至 3 月的平均值相比)

到目前为止,我有:

library(ncdf4)
library(raster)

Rname <- 'F:/extracted_rain.nc'
rainfall <- nc_open(Rname)
readRainfall <- ncvar_get(rainfall, "rain") #"rain" is float name
raster_rainfall <- raster(Rname, varname = "rain") # also tried brick()
asdatadates <- as.Date(rainfall$dim$time$vals/24, origin='1998-01-01') #The time interval is per 24 hours

我的第一个挑战是计算每个栅格单元的月平均值。我不确定在牢记最终目标(累积比较)的同时如何最好地进行。如何轻松访问某个月份的几天?

raster(readRainfall[,,500])) # doesn't seem like a straightforward approach

希望我把我的问题说清楚了,我们将不胜感激朝正确方向迈出的第一步。此处的示例数据

4

3 回答 3

5

该问题要求在 R 中提供解决方案,但如果有人希望执行此任务并想要一个简单的替代命令行解决方案,那么这些统计数据就是 CDO 的基础

月平均值:

cdo monmean in.nc monmean.nc

年平均值:

cdo yearmean in.nc yearmean.nc

取所有 1 月、2 月等的平均值:

cdo ymonmean in.nc ymonmean.nc

相对于长期年度周期的月度异常:

cdo sub monmean.nc ymonmean.nc monanom.nc

然后你想要一个特定的月份,只需用 selmon 或 seldate 选择。

您可以使用系统命令从 R 中调用这些函数。

于 2018-02-22T09:06:46.983 回答
3

这是使用zoo-package 的一种方法:

### first read the data
library(ncdf4)
library(raster)
library(zoo)

### use stack() instead of raster
stack_rainfall <- stack(Rname, varname = "rain")

### i renamed your "asdatadates" object for simplicity
dates <- as.Date(rainfall$dim$time$vals/24, origin='1998-01-01') 

在您的示例数据集中,您只有 18 层,全部来自 1998 年 1 月。但是,以下内容也应该适用于更多层(月)。首先,我们将构建一个函数,该函数对一个值向量(即像素时间序列)进行操作,以将输入转换为zoo对象,dates并使用 计算平均值aggregate。该函数返回一个向量,其长度等于 中的月数dates

monthly_mean_stack <- function(x) {
    require(zoo)
    pixel.ts <- zoo(x, dates)
    out <- as.numeric(aggregate(pixel.ts, as.yearmon, mean, na.rm=TRUE))
    out[is.nan(out)] <- NA     
    return(out)
}

然后,根据您是希望输出为矢量/矩阵/数据框还是希望保持栅格格式,您可以在使用 检索单元格值后将该函数应用于单元格值getValues,也可以使用calc- 函数中的raster-包以创建栅格输出(这将是一个栅格堆栈,其层数与您的数据中的一个月一样多)

v <- getValues(stack_rainfall) # every row displays one pixel (-time series)


# this should give you a matrix with ncol = number of months and nrow = number of pixel
means_matrix <- t(apply(v, 1, monthly_mean_stack))

means_stack <- calc(stack_rainfall, monthly_mean_stack)

当您使用大型栅格数据集时,您还可以使用该函数并行应用您的clusterR函数。看 ?clusterR

于 2016-12-20T22:55:06.773 回答
0

我认为最容易转换为栅格砖然后转换为 data.frame。

然后可以使用通用代码很容易地提取统计数据 DF$weeklymean <- rowMeans(DF[, ])

于 2020-02-12T05:18:16.097 回答