我正在尝试从.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包创建NetCDFxvals <- 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和其他变量?
有人可以解决一些问题吗?
PS:这里使用的数据不是我的真实数据,只是我用于教程的一些例子。
答案 0 :(得分:1)
我认为您的代码中存在多个问题。一步一步:
创建尺寸
在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指定的位置开始顺序写入。要写入的维度由count中的值控制。如果你有这样的数据:
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)
请注意,您不需要start
和count
。
最后关闭nc文件以将数据写入磁盘nc_close(ncnew)
我建议您选择使用ncdump
控制台命令检查文件。
修改强>
关于您是编写完整数组还是使用start
和count
的问题,我相信这两种方法都可靠。哪一个更喜欢取决于您的数据,而您是个人偏好。
我认为构建数组,添加值然后将其整体编写的方法更容易理解。但是,当询问什么更有效时,它取决于数据。如果您的数据很大且有很多NA值,我相信使用多次写入时启动和计数可能会更快。如果NA很少创建一个矩阵并且单次写入会更快。如果您的数据如此之大,那么创建额外的数组会超出您的可用内存,您必须将这两种方法结合起来。