r - 编写netcdf时设置坐标系

标签 r netcdf

我在 R 中有一个 SpatialPointsDataFrame,我想将其保存为 netCDF。我需要一些格式化方面的帮助。

> str(swe)
Formal class 'SpatialPointsDataFrame' [package "sp"] with 5 slots
  ..@ data       :'data.frame': 3487 obs. of  5 variables:
  .. ..$ site   : Factor w/ 6 levels "Dry Lake","Joe Wright",..: 1 1 1 1 1 1 1 1 1 1 ...
  .. ..$ depth  : num [1:3487] 151 157 138 155 145 ...
  .. ..$ density: num [1:3487] 0.37 0.37 0.37 0.37 0.37 0.37 0.37 0.37 0.37 0.37 ...
  .. ..$ swe.obs: num [1:3487] 0.56 0.582 0.512 0.572 0.535 ...
  .. ..$ date   : Date[1:3487], format: "2008-04-04" "2008-04-04" ...
  ..@ coords.nrs : num(0) 
  ..@ coords     : num [1:3487, 1:2] -107 -107 -107 -107 -107 ...
  .. ..- attr(*, "dimnames")=List of 2
  .. .. ..$ : NULL
  .. .. ..$ : chr [1:2] "utm.e" "utm.n"
  ..@ bbox       : num [1:2, 1:2] -107.9 37.8 -104.1 43.8
  .. ..- attr(*, "dimnames")=List of 2
  .. .. ..$ : chr [1:2] "utm.e" "utm.n"
  .. .. ..$ : chr [1:2] "min" "max"
  ..@ proj4string:Formal class 'CRS' [package "sp"] with 1 slots
  .. .. ..@ projargs: chr "+proj=longlat +datum=NAD83 +ellps=GRS80 +towgs84=0,0,0"

我有一个不规则的日期字段,因此我认为我不能将其用作维度。这些是对雪的现场测量,因此调查大约在两个不同的年份每月一次。然而,我确实需要包含每次测量的日期和站点名称。我还需要保留投影信息。以下是我到目前为止所拥有的:

require(ncdf4)
varlat=ncdim_def(name='latitude',units='deg',vals=coordinates(swe)[,2])
varlong=ncdim_def(name='longitude',units='deg',vals=coordinates(swe)[,1])
varswe=ncvar_def(name='swe.obs',units='meters',dim=list(varlat,varlong),missval=-9999)
varsite=ncvar_def(name='site',units='site',dim=list(varlat,varlong),missval=-9999)
vardate=ncvar_def(name='date',units='day',dim=list(varlat,varlong),missval=-9999)
new.nc=nc_create('snow.survey.nc',vars=list(varswe,varsite,vardate))

但是当我尝试用以下内容填充值时:

 ncvar_put(new.nc,varid=varswe,vals=swe$swe.obs)
Error in ncvar_put(new.nc, varid = varswe, vals = swe$swe.obs) : 
  ncvar_put: error: you asked to write 12159169 values, but the passed data array only has 3487 entries!

这里是 new.nc:

> new.nc
[1] "File snow.survey.nc (NC_FORMAT_CLASSIC):"
[1] ""
[1] "     3 variables:"
[1] "        float swe.obs[latitude,longitude]   "
[1] "            units: meters"
[1] "            _FillValue: -9999"
[1] "        float site[latitude,longitude]   "
[1] "            units: site"
[1] "            _FillValue: -9999"
[1] "        float date[latitude,longitude]   "
[1] "            units: day"
[1] "            _FillValue: -9999"
[1] ""
[1] "     2 dimensions:"
[1] "        latitude  Size:3487"
[1] "            units: deg"
[1] "            long_name: latitude"
[1] "        longitude  Size:3487"
[1] "            units: deg"
[1] "            long_name: longitude"

另外,如何在 netcdf 文件中定义投影字符串?在这种情况下,“+proj=longlat +datum=NAD83”,以便其他用户知道他们正在处理什么? 谢谢

更新1: 我根据@Spacedman尝试了这个,但仍然收到错误。我是否需要制作坐标范围的规则网格,然后尝试将其用作维度的范围?我不会在没有数据点的地方填写 NA。我也没有均匀间隔的测量结果。

coords=cbind(coordinates(swe)[,1],coordinates(swe)[,2])
nccoords=ncdim_def(name='coords',units='site',vals=coords)
varswe=ncvar_def(name='swe.obs',units='meters',dim=nccoords,missval=-9999,longname='survey points')

创建新的“new.nc”目前已简化为一个变量。

new.nc=nc_create('snow.survey.nc',vars=varswe)
ncvar_put(new.nc,varid=varswe,vals=swe$swe.obs)
Error in ncvar_put(new.nc, varid = varswe, vals = swe$swe.obs) : 
  ncvar_put: error: you asked to write 6974 values, but the passed data array only has 3487 entries!

最佳答案

你的尺寸发生了变化。您的经纬度数据应保存在 3487x2 维度变量中,属性应保存在 3487x1 变量中。您已经创建了尺寸为 3487x3487 的事物(varswe、varsite...)。这不是网格。

如果您的点位于网格上(如果完整,则必须是 317x11 网格),那么您需要获取唯一的纬度和经度值,并为这些值创建长度为 317 和 11 的尺寸。

关于r - 编写netcdf时设置坐标系,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18090746/

相关文章:

Python - 从 netCDF 文件读取数据,时间为 "seconds since"测量开始

shared-libraries - 安装 netCDF4 时“找不到 hdf5 库”

r - 使用 glmulti() 在详尽的所有子集回归中一次可以使用的最大变量数是多少

r - 生成向量中每个项目的 n 个随机对

从数据框单元格中读取类似值的列表

r - 如何在函数内的数据框中添加列

r - 使用 R 创建一个 n x n 计数矩阵

python - Xarray : ValueError: dimensions or multi-index levels ['lons' , 'lats'] 不存在

compression - 使用 gdal_translate 将 Geotiff 转换为 NetCDF : Huge increase in filesize

python - Xarray 获取数据集中每个月的每小时平均值(无需手动循环?)