R中netCDF文件的月平均值

时间:2016-12-20 15:11:29

标签: r netcdf4

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

  • 每月&年平均
  • 累积比较(例如jan-mar与所有jan-mar的平均值相比)

到目前为止,我有:

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

希望我明白我的问题,对正确方向的第一次推动将非常感激。 样本数据 here

3 个答案:

答案 0 :(得分:1)

以下是使用zoo - 包的一种方法:

### 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

答案 1 :(得分:0)

这些统计数据是CDO的基础和黄油

每月平均值:

cdo monmean in.nc monmean.nc

年平均值:

cdo yearmean in.nc yearmean.nc

制作所有Jan,Feb等的平均值:

cdo ymonmean in.nc ymonmean.nc

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

cdo sub monmean.nc ymonmean.nc monanom.nc

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

答案 2 :(得分:0)

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

然后可以使用通用代码DF $ weeklymean <-rowMeans(DF [,])

轻松获取统计信息