我认为您的代码中存在多个问题。一步步:
创建尺寸
在 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))
在我工作的地方,我们使用无限的维度作为纯粹的索引,而与维度同名的一维变量保存值。我不确定无限维度在 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 )
add data
创建一个 nc 文件:ncnew <- nc_create(f, list(var_temp, var_rh))
添加值时,保存数据的对象将熔化为一维数组,并在 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)
请注意,您不需要start
and count
.
最后关闭nc文件将数据写入磁盘nc_close(ncnew)
我可以选择向您推荐ncdump
控制台命令来检查您的文件。
Edit
关于你的问题是写一个完整的数组还是使用start
and count
我相信这两种方法都是可靠的。选择哪一种取决于您的数据和您的个人喜好。
我认为构建数组,将值相加然后整体写入的方法更容易理解。然而,当问什么更有效时,这取决于数据。如果您的数据很大并且有很多 NA 值,我相信使用带有开始和计数的多次写入可能会更快。如果 NA 很少见,则创建一个矩阵并进行单次写入会更快。如果您的数据太大,创建额外的数组将超出您的可用内存,您必须结合使用这两种方法。