简体   繁体   English

R 中 netCDF 文件的月平均值

[英]Monthly average from netCDF files in R

I have one netCDF file (.nc) with 16 years(1998 - 2014) worth of daily precipitation (5844 layers).我有一个 netCDF 文件 (.nc),其中包含 16 年(1998 - 2014)年的日降水量(5844 层)。 The 3 dimensions are time (size 5844), latitude (size 19) and longitude (size 20) Is there a straightforward approach in R to compute for each rastercell: 3 个维度是时间(大小为 5844)、纬度(大小为 19)和经度(大小为 20)在 R 中是否有一种直接的方法来计算每个栅格单元:

  • Monthly & yearly average月平均和年平均
  • A cummulative comparison (eg jan-mar compared to the average of all jan-mar)累积比较(例如 jan-mar 与所有 jan-mar 的平均值相比)

So far I have:到目前为止,我有:

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

My first challenge will be the compuatation of monthly averages for each raster cell.我的第一个挑战是计算每个栅格单元的月平均值。 I'm not sure how best to proceed while keeping the ultimate goal (cummulative comparison) in mind.我不确定在牢记最终目标(累积比较)的同时如何最好地进行。 How can I easily access only days from a certain month?如何轻松访问某个月份的几天?

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

Hopefully I made my question clear, a first push in the right direction would be much appreciated.希望我把我的问题说清楚了,第一次朝着正确的方向努力将不胜感激。 Sample data here示例数据在这里

Here is one approach using the zoo -package:这是使用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') 

In your example dataset you only have 18 layers, all coming from January 1998. However, the following should also work with more layers (months).在您的示例数据集中,您只有 18 个图层,全部来自 1998 年 1 月。但是,以下内容也应该适用于更多图层(月)。 First, we will build a function that operates one one vector of values (ie pixel time series) to convert the input to a zoo object using dates and the calculates the mean using aggregate .首先,我们将构建一个函数,该函数操作一个值向量(即像素时间序列),以使用dates将输入转换为zoo对象,并使用aggregate计算平均值。 The function returns a vector with the length equal to the number of months in dates .该函数返回一个向量,其长度等于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)
}

Then, depending on whether you want the output to be a vector / matrix / data frame or want to stay in the raster format, you can either apply the function over the cell values after retrieving them with getValues , or use the calc -function from the raster -package to create a raster output (this will be a raster stack with as many layers as there a months in your data)然后,根据您是希望输出是向量/矩阵/数据框还是希望保持栅格格式,您可以在使用getValues检索单元格值后将该函数应用于单元格值,或者使用calc函数来自该raster -package创建光栅输出(这将是一个光栅堆栈的许多层为你的数据有没有个月)

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)

When you're working with large raster datasets you can also apply your functions in parallel using the clusterR function.当您处理大型栅格数据集时,您还可以使用clusterR函数并行应用您的函数。 See ?看 ? clusterR

The question asked for a solution in R, but in case anyone is looking to do this task and wants a simple alternative command-line solution, these kind of statistics are the bread and butter of CDO该问题要求在 R 中找到解决方案,但如果有人希望完成此任务并想要一个简单的替代命令行解决方案,则此类统计数据是 CDO 的基础

Monthly averages:每月平均值:

cdo monmean in.nc monmean.nc

Annual averages:年平均值:

cdo yearmean in.nc yearmean.nc

Make the average of all the Jan, Feb etc:取所有 1 月、2 月等的平均值:

cdo ymonmean in.nc ymonmean.nc

The monthly anomaly relative to the long term annual cycle:相对于长期年度周期的月度异常:

cdo sub monmean.nc ymonmean.nc monanom.nc

Then you want a specific month, just select with selmon, or seldate.然后你想要一个特定的月份,只需选择 selmon 或 seldate。

I think easiest to convert to raster brick and then into a data.frame.我认为最容易转换为光栅砖,然后转换为 data.frame。

Then can pull stats quite easily using general code DF$weeklymean <- rowMeans(DF[, ])然后可以很容易地使用通用代码 DF$weeklymean <- rowMeans(DF[, ])

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM