使用R转换为NetCDF时保留栅格变量名称 [英] Keeping raster variable names when converting to NetCDF using R

查看:131
本文介绍了使用R转换为NetCDF时保留栅格变量名称的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

获取多年的每月温度数据的栅格文件,该文件的名称可以通过names(object)附加,格式为"1981年1月","1981年2月"等(两年的示例文件与代码兼容)在此处下面-添加所有文件会使文件太大.

Taking a raster file of monthly temperature data for multiple years which has a name attached accessible via names(object) in the following format 'Jan.1981', 'Feb.1981' etc (example files for two years that works with code below here - adding all files makes it too big.

使用以下代码读取并将其写入NetCDF:

Reading in and writing this to NetCDF using the following code:

#Load Packages
library(raster)
library(ncdf4)

#Read in temperature files
r1 <- brick('TavgM_1981.grd')
r2 <- brick('TavgM_1982.grd')

#stack them together 
TempStack = stack(r1, r2)

#set the coordinate system (as it was missing)
crs(TempStack) <- ('+proj=lcc +lat_1=53.5 +lat_2=53.5 +lat_0=46.834 +lon_0=5 +x_0=1488375 +y_0=-203375 +datum=WGS84 +to_meter=2500 +no_defs +ellps=WGS84 +towgs84=0,0,0')

#reproject to get in lat/lon instead of meters
TempStack<-projectRaster(TempStack, crs=CRS("+init=epsg:4326"))

#Extract monthly data names to assign to netCDf later
names <- names(TempStack)

#write the raster file to NetCDF
writeRaster(TempStack, "Temp.nc", overwrite=TRUE, format="CDF",     varname="Temperature", varunit="degC", 
        longname="Temperature -- raster stack to netCDF, monthly average", xname="Longitude",   yname="Latitude", zname='Time', zunit=names)

当我将其写到NetCDF并绘制从1个月到24个月的月度数据时,但我希望它具有"1981年1月","1981年2月"等.

When I write this to NetCDF and plot the monthly data it is organised from month 1 to month 24, but I want it to have 'Jan 1981', 'Feb 1981' etc.

我认为通过在writeRaster中添加zunit参数会起作用,但事实并非如此,数字仍然是1-24,而不是Jan,Feb等.

I thought by adding the zunit argument in writeRaster would work, but it doesn't, the numbers are all still 1-24 instead of Jan, Feb etc.

推荐答案

您的示例中有一些误解.首先,您应该意识到netcdf维度中的值必须是数字.它们不仅是图层的标签,而且是该维度的实际值,因此不能采用类似字符串的"Jan.1980"这样的值.解决此问题的一种方法是保存netcdf文件,然后将z尺寸值添加为数字值.不幸的是,这意味着我们也不能使用日期/时间变量类型,但必须首先将它们转换为等效的数字.在这里,我使用lubridate包来做到这一点.

There are a couple of misconceptions in your example. First, you should realize that the values in a netcdf dimension must be numeric. They are not just labels for layers, they are actual values of that dimension, and cannot therefore take values like "Jan.1980", which is a string. One way around this is to save your netcdf file and then add the z dimension values to it as a numeric value. Unfortunately that means we can't use date/time variable types either, but must first convert them to numeric equivalents. Here I use the lubridate package to do that.

# first we write the netcdf file to disk
writeRaster(TempStack, "Temp.nc", overwrite=TRUE, 
            format="CDF",     varname="Temperature", varunit="degC", 
            longname="Temperature -- raster stack to netCDF, monthly average", 
            xname="Longitude",   yname="Latitude", zname='Time', zunit='seconds')

# and open a connection to it to make changes.
# note that we use write=TRUE so that we can change it
nc = nc_open('Temp.nc', write = TRUE)

# now convert the strings to numeric values based on their dates
zvals = lubridate::parse_date_time(names, orders = 'm.y', tz = "UTC")
zvals = as.integer(zvals)

# and we can write these numeric dates to the z dimension
ncdf4::ncvar_put(nc, 'Time', zvals)

像这样将日期写到z维度上,如果要将z数值转换回看起来像"Jan.1908"等的栅格图层名称,我们还需要扭转该过程.同样,lubridate可以帮助.

Haing written the dates to the z dimension like this, we will also need to reverse the process if you want to convert the numeric z values back into raster layer names that look like "Jan.1908" etc. Again, lubridate can help.

ncb = brick('Temp.nc')
zvals = ncvar_get(nc, 'Time')
zvals =  as.POSIXct(zvals, origin = lubridate::origin, tz = "UTC")
znames = paste0(lubridate::month(zvals, label=T), '.', lubridate::year(zvals))
names(ncb) = znames

让我们检查一下是否有效:

Let's check that worked:

plot(ncb)

这篇关于使用R转换为NetCDF时保留栅格变量名称的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆