我有一个 .nc 文件,其中包含一整年的每日数据,我试图计算每个月的平均值。
我尝试使用
netCDF Operator (NCO)提供的Linux命令
ncra
。
结果似乎没有错,因为输出文件的时间戳是每个月的中间日期。
但是,当我使用 terra::tapp(daily_nc, indices2, fun = mean)
仔细检查我的结果时,似乎 ncra
得到了不同的平均值
NCO::ncra | terra::tapp |
---|---|
251.8105 | 251.9165 |
这是我使用的完整代码:
# load pacakges
require(pacman)
pacman::p_load(dplyr, tidyverse, terra, RColorBrewer, scales)
wd <- '~/RA/CMIP6/'
base <- 'https://nex-gddp-cmip6.s3-us-west-2.amazonaws.com/NEX-GDDP-CMIP6'
mdl <- 'ACCESS-CM2'
prd <- 'historical'
var <- 'tasmax'
# download data
urli <- paste0(base, '/', mdl, '/', prd, '/', 'r1i1p1f1', '/', var, '/', var, '_day_', mdl, '_', prd, '_', 'r1i1p1f1', '_gn_2000.nc')
setwd(wd)
system(paste0("axel -a -n 5 ", urli))
file.name <- paste0(var, '_day_', mdl, '_', prd, '_', 'r1i1p1f1', '_gn_2000.nc')
# ---------- ncra ----------------
# initial date for month
days_start <- seq(as.Date(paste0("2000-01-01")), length = 12, by = "months")
days_end <- seq(as.Date(paste0("2000-02-01")), length = 12, by = "months") - 1
# monthly mean
for(m in 1:12){
system(paste0('ncra -O -d time,"', days_start[m], '","', days_end[m], '" ', wd, file.name, ' ', wd, 'monthly_', m, '.nc'))
}
# stack monthly mean in one .nc file
system(paste0('ncrcat ', wd, 'monthly_*.nc ', wd, gsub('day', 'month' , file.name)))
# delete intermediate files
system(paste0('rm ', wd, 'monthly_*.nc'))
r_nco <- rast(paste0(wd, gsub('day', 'month' , file.name)))
# ------------ terra::tapp -----------------
r <- rast(paste0(wd, file.name))
indices <- format(time(r), format = "%m") %>%
as.double()
r_terra <- tapp(r, indices, fun = mean)
time(r_terra) <- seq(as.Date(paste0("2000-01-15")), length = 12, by = "months")
# ---------- plot and compare --------------
col <- brewer_pal(palette = "RdYlBu", direction = -1)(5)
plot(r_nco, col = col)
plot(r_terra, col = col)
# find a pixel with value in 2000.01
time(r_nco)
r_nco[[1]][90490]
time(r_terra)
r_terra[[1]][90490]
NCO 的行为几乎与@Robert Wilson 上面的评论一样。除非另有说明,否则 NCO 会将磁盘类型转换为双精度,进行算术运算,然后再转换回输入/输出类型。如果
terra::tapp
方法以不同方式处理数据,这可以解释差异。