0

我有 73 个 netCDF 文件,每个文件代表一个日历年的 5 天间隔,并且有几个变量。每个文件有 120 个层,代表每小时的间隔。

我已将它们全部读入 R 并使用ncdf4包适当地命名它们,如下所示:

filenames <- list.files(path=getwd()) 

for(i in filenames) {
  ncin <- nc_open(i)
  ds<-paste(i)
  assign(ds, ncin)
  print(i)
  }

我在与 netCDF 文件(经纬度)相同的投影中也有一个位置数据框,但是这些位置也不规则地跨越整个日历年。数据样本如下所示:

>head(df)
> Lon      Lat            datetime
2 -3.179046 58.65417 2016-09-30 17:25:38
3 -3.180403 58.65483 2016-09-30 17:29:43
4 -3.187734 58.66102 2016-09-30 21:22:51
5 -3.190197 58.66409 2016-09-30 22:02:47
6 -3.182058 58.67433 2016-10-01 06:16:08
7 -3.181318 58.67475 2016-10-01 06:20:31

我要做的是根据日期时间戳将数据框与正确的 netCDF 文件和图层匹配,即如果它在一年的第 1 天和第 5 天之间,它将是 netCDF 文件 1 等。然后我想插值将 netCDF 文件中的可变数据与数据帧的相关日期时间戳关联到位置数据上。因此,在数据框提供的给定时间和地点,netCDF 文件中同一日期和时间的变量 V 的值是多少。我可以使用循环函数来完成第一部分,但编码效率非常低且耗时:

function(dataframe){
d <- dataframe[i,]
if(between(d$datetime, 2017-01-01 00:00:00, 2017-01-05 23:59:59){ncfile <- file1} else if (between(d$datetime, 2017-01-06 00:00:00, 2017-01-010 23:59:59)) 
     {ncfile <- file2}}

等等...在我不确定最佳方法之前从未使用过 netCDF 文件。有什么建议么?

################# 更新

我在使用中阅读了 netCDF 文件

filenames <- list.files(path=getwd()) 
x <- lapply(filenames, nc_open)

从文件中提取按顺序命名的日期:

PFOW_Climatology2_0001_1993-01-01.nc
PFOW_Climatology2_0002_1993-01-06.nc

取决于

PFOW_Climatology2_0073_1993-12-27.nc

通过使用

fd <- as.Date(substr(filenames, 24, 36))

然后,我通过 find9ing 每个数据点在 fd 中对应的间隔为数据框创建一个参考列,如下所示:

i <- findInterval(dd, fd) 
df$file <- i
4

1 回答 1

2

如果不提供更多信息,最好是一些示例数据,很难给出一个好的答案。

您的“适当命名”非常不合适。你真的不应该 assign在日常生活中需要。列个清单就行了。

library(ncdf4)
x <- lapply(filenames, nc_open)

但是由于您需要按位置提取值,因此最好制作一个 RasterBrick 对象列表:

library(raster)
x <- lapply(filenames, brick)

但我也不会那样做。

我首先将文件名与 df$datetime 匹配。由于您没有告诉我们文件名是什么样的,我无法告诉您如何做到这一点。但是你不需要循环。从文件名中提取日期,创建适当的日期(和时间?)对象并执行类似的操作

fd <- as.Date(subtr(filenames, 4, 12))
dd <- as.Date(df$datetime)
i <- which(dd > fd[-length(fd)] & dd < fd[-1]) + 1 

df$file <- filenames[i]
df$id <- 1:nrow(df)

现在您可以遍历文件名并提取值:

ff <- unique(df$file)
vv <- sapply(ff, function(f) {
         v <- extract(brick(f), df[df$file == f , c('lon', 'lat')])
         data.frame(file=f, xy, v)
      })

vv应该是一个 data.frame,每个案例的值,对应的 5 天间隔。从那里从 120 个值中选择(或插入)您想要的时间。

我假设你想做时间插值。对于(也)空间插值method = 'bilinear'使用extract

同样,这可能不起作用,因为我没有示例数据。但是沿着这些路线的东西会起作用。

于 2017-11-16T01:56:59.100 回答