CMIP6,按月自动化

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

提前感谢您的任何见解/帮助。我还在学习/R 新手。

我正在跨多个模型处理多个变量的 CMIP6 历史数据。理想情况下,我的基线是从 1850 年到 1950 年。在这个例子中,我有 2 个不同气候模型的每月温度数据,我想跨 6 个模型进行工作。两种模型都使用“自 1850 年 01 月 1 日以来的天数”来计算以 29.5 天为增量的时间。创建数组后,我可以在 1、13、25 等位置切出数据来表示给定的月份/年份。

我想提取每个月每个历史时间段的平均值数据。因此,100 年来平均每月一个数据层/文件。我编写了代码来提取单个模型的单个月份、单个年份,但这对于 1850 - 1950 年甚至 1900 - 1950 年的基线来说是残酷的。(100 年 * 12 个月 * 6 个模型 = 72,000 行代码)。

是否有 for 循环或其他更优雅/简单的方法来使其可行?当我说我是 R 新手时,我无法使用这种数据结构编写 for 循环。

我宁愿避免减少年数和型号数量,以使其成为可行的提升。我可以复制粘贴并手动调整,但这会非常耗时,而且我知道更有经验的程序员正在摇头/嘲笑我:)

我正在使用以下(极其简单、不优雅)代码:

library(raster)
library(RNetCDF)
library(ncdf4)

####open .nc file for each model, variable, and time period###

nc_data <- nc_open('tas_Amon_GFDL-CM4_historical_r1i1p1f1_gr1_185001-194912.nc')
nc_data2 <- nc_open('tas_Amon_GISS-E2-1-G_historical_r101i1p1f1_gn_185001-194912.nc')

lon <- ncvar_get(nc_data, "lon_bnds")
lat <- ncvar_get(nc_data, "lat_bnds")
t <- ncvar_get(nc_data, "time_bnds")

lon2 <- ncvar_get(nc_data2, "lon_bnds")
lat2 <- ncvar_get(nc_data2, "lat_bnds")
t2 <- ncvar_get(nc_data2, "time_bnds")

head(t)
nc_data$dim ###QA/QC: lat len 180; lon len 288; time len 1200; note time $vals starts at 15.5,then increases by 29.5 thereafter, e.g. 15.5, 45.0, 74.5 etc###

tas.arrayGFDL <- ncvar_get(nc_data, "tas") ###store the data in a 3-dimensional array###
dim(tas.arrayGFDL) ###QA/QC matches the length given nc_data$dim)###

tas.jan1850GFDL <- tas.arrayGFDL[, , 1] ###first slice is jan 1850###
dim(tas.jan1850GFDL) ##correct lat, lon##

tas.jan1851GFDL <- tas.arrayGFDL[, , 13] ###13th slice is jan 1851###
dim(tas.jan1851GFDL) ##correct lat, lon##

tas.jan1850rGFDL<- raster(t(tas.jan1850GFDL), xmn=min(lon), xmx=max(lon), ymn=min(lat), ymx=max(lat), crs=CRS("+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs+ towgs84=0,0,0"))
tas.jan1851rGFDL<- raster(t(tas.jan1850GFDL), xmn=min(lon), xmx=max(lon), ymn=min(lat), ymx=max(lat), crs=CRS("+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs+ towgs84=0,0,0"))

plot(tas.jan1850rGFDL)
[![Jan 1850 GFDL GCM][1]][1]
plot(tas.jan1851rGFDL)

tas.jan1850rfGFDL <- flip(tas.jan1850rGFDL, direction='y')
tas.jan1851rfGFDL <- flip(tas.jan1851rGFDL, direction='y')

plot(tas.jan1850rfGFDL)
[![enter image description here][2]][2]
plot(tas.jan1851rfGFDL)

writeRaster(tas.jan1850rfGFDL, "tas.jan1850rfGFDL.tif", "GTiff", overwrite=TRUE)

writeRaster(tas.jan1851rfGFDL, "tas.jan1851rfGFDL.tif", "GTiff", overwrite=TRUE)

###然后对每个月、每年、每个型号重复此操作。###

r bigdata
1个回答
0
投票

看起来这个包

processNC
大致满足您的需求:

概述

processNC 是一个 R 包,用于在 R 中处理和分析 NetCDF 文件。 NetCDF 文件可以使用 R 中 terra 包中的 rast() 函数轻松加载到 R 中,或者以前也使用 R 中的 raster() 函数光栅包。但是,当尝试处理大型 NetCDF 文件时,直接使用 ncdf4 软件包或气候数据操作员软件可能会更方便,并且此软件包为这两个选项提供了简化的包装器。

需要此软件包的任务是加载带有全球每日气候数据的大型 NetCDF 文件以计算月度或年度平均值。使用此软件包可以更快地完成此任务,而无需将整个文件读入内存。

具体来说,主页上包含的示例之一是如何按月汇总多年的:

# Summarise daily NetCDF file for 10 years first by month and then by year
s <- summariseNC(files=tas_files[4], startdate=2001, enddate=2010,
                 group_col=c("month", "year"))
s
class       : SpatRaster 
dimensions  : 15, 18, 12  (nrow, ncol, nlyr)
resolution  : 0.5, 0.5  (x, y)
extent      : 6, 15, 47.5, 55  (xmin, xmax, ymin, ymax)
coord. ref. :  
source(s)   : memory
names       : January, February,  March,  April,    May,   June, ... 
min values  :  269.81,   271.11, 274.13, 278.36, 283.22, 286.39, ... 
max values  :  276.14,   277.16, 280.17, 284.59, 288.88, 292.26, ... 

您仍然需要为每个模型执行此操作。我建议花一点时间学习如何使用 R 的矢量化迭代工具:

purrr::map
教程)或基础 R 的
lapply
。这样做而不是复制粘贴,不仅因为节省了时间(对于只有六个模型来说不会那么多),而且因为它确保您执行完全相同的处理每个型号的方式。

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