R从.CSV创建NetCDF

时间:2015-12-07 17:28:59

标签: r gis netcdf

我正在尝试从.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和其他变量?

有人可以解决一些问题吗?

PS:这里使用的数据不是我的真实数据,只是我用于教程的一些例子。

1 个答案:

答案 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)

请注意,您不需要startcount

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

修改

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

我认为构建数组,添加值然后将其整体编写的方法更容易理解。但是,当询问什么更有效时,它取决于数据。如果您的数据很大且有很多NA值,我相信使用多次写入时启动和计数可能会更快。如果NA很少创建一个矩阵并且单次写入会更快。如果您的数据如此之大,那么创建额外的数组会超出您的可用内存,您必须将这两种方法结合起来。