Расширение размеров в файле netCDF с использованием R

Я хотел бы написать файл netCDF с использованием R с "неограниченными" размерами, которые я впоследствии могу расширить.

Вот что я пробовал:

Создать файл netcdf

library(ncdf4)

## define lat, lon time dimensions
lat <- ncdim_def("latitude", "degrees_east", vals =  44.0, unlim = TRUE) 
lon <- ncdim_def("longitude", "degrees_north", vals = -88.5, unlim = TRUE)
time <- ncdim_def("time", "days since 0000-01-01", 1:1000)

## define data with these dimensions
x <- ncvar_def("myvar", units = "m2", dim = list(lat, lon, time))

## create, write to, close nc file
nc <- nc_create(filename = "tmp.nc", vars = list(x))

ncvar_put(nc = nc, varid = x, vals = 1:1000)
nc_close(nc = nc)

Я хочу добавить новый вектор в другой lat и lon

## reopen existing file
nc <- nc_open("tmp.nc", write = TRUE)

## define new lat, lon dimensions (keep time dim from above)
lat2 <- ncdim_def("latitude", "degrees_east", vals =  44.5, unlim = TRUE) 
lon2 <- ncdim_def("longitude", "degrees_north", vals = -89.0, unlim = TRUE)

## define, write new dataset at new lat lon coordinates
x2 <- ncvar_def("myvar", units = "m2", dim = list(lat2, lon2, time))
ncvar_put(nc = nc, varid = x2, vals = 11:1011)

Я ожидал бы найти две разные широты и долготы

ncvar_get(nc, 'latitude')
ncvar_get(nc, 'longitude')

ncvar_get(nc, 'myvar')

Это показывает, что файл был написан с использованием первого набора значений lat/lon и 'myvar', но не был добавлен с новым набором значений.

Что я делаю неправильно?

Я знаю, что способность иметь несколько неограниченных размеров и добавлять к ним функцию функции netCDF-4. Как это сделать в R?

Я понимаю, что я должен путать "определение измерения" с каким-то другим понятием. Но я немного потерял.

Ответ 1

Да, я думаю, вы вводите в заблуждение "определение размеров" и фактические данные в переменной измерения.

Если вы запустите свой первый фрагмент кода и затем выгрузите файл NetCDF с помощью ncdump, вы увидите:

netcdf tmp {
dimensions:
        latitude = UNLIMITED ; // (1 currently)
        longitude = UNLIMITED ; // (1 currently)
        time = 1000 ;
variables:
        double latitude(latitude) ;
                latitude:units = "degrees_east" ;
                latitude:long_name = "latitude" ;
        double longitude(longitude) ;
                longitude:units = "degrees_north" ;
                longitude:long_name = "longitude" ;
        int time(time) ;
                time:units = "days since 0000-01-01" ;
                time:long_name = "time" ;
        float myvar(time, longitude, latitude) ;
                myvar:units = "m2" ;
data:

 latitude = 44 ;

 longitude = -88.5 ;

 time = 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
    20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33,
    ...
    990, 991, 992, 993, 994, 995, 996, 997, 998, 999, 1000 ;

 myvar =
  {{1}},
  {{2}},
  {{3}},
  ...
  {{1000}} ;
} 

Размеры говорят, что latitude и longitude не ограничены, а размер time фиксирован в 1000 пунктов/дней с 0000-01-01. Это именно то, что вы указали, что хорошо.

Итак, добавим еще одну широту и долготу. Я снова открою файл, прочитаю текущие данные, добавлю его, а затем запишу обратно.

library(ncdf4)
nc <- nc_open("tmp.nc", write = TRUE)
lat <- ncvar_get(nc, varid='latitude')
lat <- append(lat, 44.5)
ncvar_put(nc, varid='latitude', vals=lat, start=c(1), count=2)
nc_close(nc)

Теперь ncdump покажет вам две широты:

data:

 latitude = 44, 44.5 ;

 longitude = -88.5 ;

Конечно, для больших наборов данных, которые вам не нужны или вы не хотите читать во всех данных и добавлении, вы можете просто указать NetCDF, где вы хотите, чтобы она была написана.

library(ncdf4)
nc <- nc_open("tmp.nc", write = TRUE)
lon = -89.0
ncvar_put(nc, varid='longitude', vals=lon, start=c(2), count=1)
nc_close(nc)

Теперь ncdump покажет вам две широты и две долготы:

data:

 latitude = 44, 44.5 ;

 longitude = -88.5, -89 ;

Данные представляют myvar - это трехмерный массив, поэтому я бы сделал первоначальную запись другой. Я бы указал его размеры при создании данных и при записи в файл, например:

data <- array(1:1000, c(1,1,1000))
ncvar_put(nc = nc, varid='myvar', vals=data, start=c(1,1,1), count=c(1,1,1000))

Затем добавьте вторую широту и долготу:

data <- array(11:1011, c(1,1,1000))
ncvar_put(nc = nc, varid='myvar', vals=data, start=c(2,2,1), count=c(1,1,1000))

Примечание

Я чувствую, что пакет R слишком скрывает от вас. Когда вы создаете измерение с помощью ncdim_def, вы можете дать ему значения. Это, на мой взгляд, более трехэтапный процесс.

  • Создайте измерение.
  • Создайте переменную, связанную с этим измерением.
  • Добавьте данные к этой переменной.

Надеюсь, что это поможет.