Сохранение имен растровых переменных при конвертации в NetCDF с использованием R - PullRequest
0 голосов
/ 01 мая 2018

Получение растрового файла с месячными данными о температуре за несколько лет, к которому прикреплено имя, доступное через names(object) в следующем формате 'Jan.1981', 'Feb.1981' и т. Д. (Примеры файлов за два года, которые работают с кодом ниже здесь - добавление всех файлов делает его слишком большим.

Чтение и запись этого в 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», «февраль 1981» и т. Д.

Я думал, что добавление аргумента zunit в writeRaster будет работать, но это не так, числа все равно 1-24 вместо января, февраля и т. Д.

1 Ответ

0 голосов
/ 07 мая 2018

В вашем примере есть несколько заблуждений. Во-первых, вы должны понимать, что значения в измерении 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)

enter image description here

...