使用R中的netcdf数据集计算网格单元格中的加权空间全局年平均值

问题描述 投票:1回答:2

我目前正在开展一个涉及存储在NetCDF文件中的气候模型数据的项目。我目前正在尝试计算降水的“加权”空间年度“全球”平均值。我需要为我拥有的95年全球降水数据中的每一个做到这一点。这个想法是以某种方式通过使用其纬度的余弦(这意味着赤道的纬度网格单元的权重为1(即0度的余弦为1))对每个网格单元应用权重,并且极点将具有值为1(因为余弦值为90为1))。然后,我可以根据每个网格单元的平均值计算年加权平均值。

我知道如何在概念上做到这一点,但我不知道从哪里开始在R中编写脚本以在所有网格单元中应用权重,然后对95年中的每一个进行平均。我非常感谢任何帮助,或任何可能有用的资源!

至少,我打开了.nc文件并读入了NetCDF变量,如下所示:

ncfname<-"MaxPrecCCCMACanESM2rcp45.nc"
Prec<-raster(ncfname)
print(Prec)
Model<-nc_open(ncfname)
get<-ncvar_get(Model,"onedaymax")
longitude<-ncvar_get(Model, "lon")
latitude<-ncvar_get(Model, "lat")
Year<-ncvar_get(Model, "Year")

另外,假设我想为特定位置或区域创建这些新衍生加权平均值的时间序列,以下代码用于显示95年来一天最大降水量的趋势,但我会只是需要稍微改一下才能使用年度加权平均值? :

r_brick<-brick(get, xmn=min(latitude), xmx=max(latitude), ymn=min(longitude),                               
ymx=max(longitude), crs=CRS("+proj=longlat +ellps=WGS84 +datum=WGS84   
+no_defs+ towgs84=0,0,0"))
r_brick<-flip(t(r_brick), direction='y')
randompointlon<-13.178
randompointlat<--59.548
Random<-extract(r_brick, 
SpatialPoints(cbind(randompointlon,randompointlat)),method='simple')
df<-data.frame(year=seq(from=1, to=95, by=1), Precipitation=t(Hope))
ggplot(data=df, aes(x=Year, y=Precipitation,   
group=1))+geom_line()+ggtitle("One-day maximum precipitation (mm/day) trend  
for Barbados for CanESM2 RCP4.5")

此外,如果它有帮助,这里是.nc文件包含的内容:

 3 variables (excluding dimension variables):
    double onedaymax[lon,lat,time]   (Contiguous storage)  
        units: mm/day
    double fivedaymax[lon,lat,time]   (Contiguous storage)  
        units: mm/day
    short Year[time]   (Contiguous storage)  

 3 dimensions:
    time  Size:95
    lat  Size:64
        units: degree North
    lon  Size:128
        units: degree East

再次,任何帮助都将是非常有价值的!我期待着您的回复!

r global spatial netcdf weighted-average
2个回答
1
投票

请一次提出一个明确的问题,并提供示例数据(通过代码)。

我认为你不会以正确的方式阅读ncdf数据。我想你应该这样做

library(raster)
ncfname <- "MaxPrecCCCMACanESM2rcp45.nc"
Prec <- brick(ncfname, var="onedaymax")

(不要使用nc_open等)

获得全球加权平均值

示例数据

library(raster)
r <- abs(init(raster(), 'y'))
s <- stack(r, r, r)

s是一个RasterStack,极点值为90,赤道值为0

未加权的全球平均值。首先平均层,然后是单元格(在这种情况下,逆序也适用)

sm <- mean(s, na.rm=TRUE)
cellStats(sm, mean, na.rm=TRUE)
[1] 45

现在使用加权(获得较低的数字是高纬度减重)

# raster with latitude cell values 
w <- init(s, 'y')
# cosine after transforming to radians
w <- cos(w  * (pi/180))
# multiply weights with values
x <- sm * w
# compute weighted average
cellStats(x, sum) / cellStats(w, sum)
#[1] 32.70567

一种替代的,也许更简单的解决方案是使用每个单元的面积(与cos(lat)成比例)。结果可能更精确一些(因为区域不仅考虑了细胞中心)。

a <- area(s) / 10000
y <- sm * a
cellStats(y, sum) / cellStats(a, sum)
#[1] 32.72697

后来:

对于时间序列,只需使用s

加权

cellStats(s, mean) 
#layer.1 layer.2 layer.3 
# 45      45      45 

加权

a <- area(s) / 10000
y <- s * a
cellStats(y, sum) / cellStats(a, sum)
# layer.1  layer.2  layer.3 
#32.72697 32.72697 32.72697 

0
投票

并不是说我想让你远离R,但这种计算是直接来自命令行的cdo(气候数据运营商)的绝对优势!

计算空间加权平均值(这可以解释纬度的误差,也可以处理减少的高斯网格等):

cdo fldmean input.nc fldmean.nc 

计算年平均值

cdo yearmean input.nc yearmean.nc

通过组合两者来计算年度全局均值的时间序列(即使用fldmean.nc作为第二个命令的输入),或者您可以通过管道在一行上执行:

cdo yearmean -fldmean input.nc yearglobal.nc

那是什么?你想为你说的lat-lon盒子区域计算它,而不是全局平均值?没问题,首先使用sellonlatbox切出一个区域

cdo sellonlatbox,lon1,lon2,lat1,lat2 in.nc out.nc 

这样管道:

cdo  yearmean -fldmean -sellonlatbox,lon1,lon2,lat1,lat2 in.nc yearregion.nc

可是等等!你现在想要一个特定的位置,而不是一个地区平均值?那么你可以选择最近的网格框到一个位置

cdo remapnn,lon=mylon/lat=mylat in.nc out.nc 

所以你可以得到你的年度平均值系列:

cdo yearmean -remapnn,lon=mylon/lat=mylat in.nc yearmylocation.nc

可能性很多......安装它

sudo apt install cdo 

并看看这里的文档:https://code.mpimet.mpg.de/projects/cdo/wiki/Cdo#Documentation

© www.soinside.com 2019 - 2024. All rights reserved.