【问题标题】:Keeping raster variable names when converting to NetCDF using R使用 R 转换为 NetCDF 时保留栅格变量名称
【发布时间】:2018-10-11 16:58:27
【问题描述】:

获取一个包含多年月度温度数据的栅格文件,其名称可通过names(object) 访问,格式如下“1981 年 1 月”、“1981 年 2 月”等(使用代码的两年示例文件低于here - 添加所有文件使其太大。

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

#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 月”等。

我认为通过在 writeRaster 中添加 zunit 参数会起作用,但它不起作用,数字仍然是 1-24 而不是一月、二月等。

【问题讨论】:

    标签: r raster netcdf r-raster ncdf4


    【解决方案1】:

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

    # 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 可以帮助。

    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
    

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

    plot(ncb)
    

    【讨论】:

    • 谢谢你 - 我没有意识到 NetCDF 维度必须是数字。转换为 UTC 意味着我也可以用 Python 来阅读它,这是一个很大的帮助。谢谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-01-26
    • 2019-09-21
    • 2017-10-02
    • 2018-02-10
    相关资源
    最近更新 更多