R create NetCDF from .CSV



我正试图从.csv文件创建一个NetCDF。我在这里和其他地方读了一些教程,但仍然有一些疑问。

我有一张这样的桌子:

lat,long,time,rh,temp
41,-109,6,1,1
40,-107,18,2,2
39,-105,6,3,3
41,-103,18,4,4
40,-109,6,5,2
39,-107,18,6,4

我使用R.中的ncdf4包创建NetCDF

xvals <- data$lon
yvals <- data$lat 
nx <- length(xvals)
ny <- length(yvals)
lon1 <- ncdim_def("longitude", "degrees_east", xvals)
lat2 <- ncdim_def("latitude", "degrees_north", yvals)
time <- data$time
mv <- -999 #missing value to use
var_temp <- ncvar_def("temperatura", "celsius", list(lon1, lat2, time), longname="Temp. da superfície", mv) 
var_rh <- ncvar_def("humidade", "%", list(lon1, lat2, time), longname = "humidade relativa", mv )
ncnew <- nc_create(filename, list(var_temp, var_rh))
ncvar_put(ncnew, var_temp, dadostemp, start=c(1,1,1), count=c(nx,ny,nt))

当我遵循该过程时,它指出NC期望的数据数量是我所拥有的数据数量的3倍。我理解为什么,每个维度都有一个矩阵,因为我说过变量是根据经度、纬度和时间的。

那么,在每次数据采集都有一个Lon、Lat、Time和其他变量的情况下,我该如何导入这种数据呢?

有人能给我点光吗?

附言:这里使用的数据不是我的真实数据,只是我在教程中使用的一些例子。

我认为您的代码中存在不止一个问题。循序渐进:

创建维度

在nc文件中,尺寸不能作为键值,只有一个值向量来定义变量数组中每个位置的含义。这意味着你应该创建这样的维度:

xvals <- unique(data$lon)
xvals <- xvals[order(xvals)]
yvals <- yvals[order(unique(data$lat))] 
lon1 <- ncdim_def("longitude", "degrees_east", xvals)
lat2 <- ncdim_def("latitude", "degrees_north", yvals)
time <- data$time
time_d <- ncdim_def("time","h",unique(time))

在我工作的地方,我们只使用无限维度作为索引,而与维度同名的1d变量则保存这些值。我不确定无限维度在R中是如何工作的。由于你没有要求它,我省略了这个:-)

定义变量

mv <- -999 #missing value to use
var_temp <- ncvar_def("temperatura", "celsius", 
                      list(lon1, lat2, time_d), 
                      longname="Temp. da superfície", mv) 
var_rh <- ncvar_def("humidade", "%", 
                     list(lon1, lat2, time_d), 
                     longname = "humidade relativa", mv )

添加数据

创建nc文件:ncnew <- nc_create(f, list(var_temp, var_rh))

当添加值时,保存数据的对象被熔化为1d数组,并且在start指定的位置开始顺序写入。要写入的维度由计数中的值控制。如果你有这样的数据:

long, lat, time, t
   1,   1,    1, 1
   2,   1,    1, 2
   1,   2,    1, 3
   2,   2,    1, 4

命令ncvar_put(ncnew, var_temp,data$t,count=c(2,2,1))将提供您(可能)期望的内容。

对于数据,第一步是为维度创建索引:

data$idx_lon <- match(data$long,xvals)
data$idx_lat <- match(data$lat,yvals)
data$idx_time <- match(data$time,unique(time))

然后创建一个尺寸适合您的数据的数组:

m <- array(mv,dim = c(length(yvals),length(xvals),length(unique(time))))

然后用你的值填充数组:

for(i in 1:NROW(data)){
  m[data$idx_lat[i],data$idx_lon[i],data$idx_time[i]] <- data$temp[i]
}

如果速度是一个问题,您可以计算矢量化的线性索引,并将其用于值分配。

写入数据

ncvar_put(ncnew, var_temp,m)

请注意,您不需要startcount

最后关闭nc文件将数据写入磁盘nc_close(ncnew)我建议您使用ncdump控制台命令来检查您的文件。

编辑

关于您的问题,是编写完整的数组还是使用startcount,我相信这两种方法都是可靠的。选择哪一个取决于你的数据和你的个人偏好。

我认为构建一个数组,添加值,然后将其作为一个整体编写的方法更容易理解。然而,当问什么更有效时,这取决于数据。如果你的数据很大,并且有很多NA值,我相信使用带开始和计数的多次写入可能会更快。如果NA很少,创建一个矩阵并进行单次写入会更快。如果你的数据太大,创建一个额外的数组会超过你的可用内存,你必须将这两种方法结合起来。

最新更新