我目前正在开展一个涉及存储在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
再次,任何帮助都将是非常有价值的!我期待着您的回复!
请一次提出一个明确的问题,并提供示例数据(通过代码)。
我认为你不会以正确的方式阅读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
并不是说我想让你远离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