【问题标题】:How to relate a function to a specific netCDF file based on timestamp如何根据时间戳将函数与特定的 netCDF 文件相关联
【发布时间】:2018-04-29 00:45:17
【问题描述】:

我有 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 文件 (lat-lon) 相同的投影中也有一个位置数据框,但是这些位置也不规则地跨越整个日历年。数据样本如下所示:

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

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

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

【问题讨论】:

    标签: r function raster netcdf netcdf4


    【解决方案1】:

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

    您的“恰当命名”非常不恰当。你真的不应该在日常生活中需要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 个值中选择(或插入)您想要的时间。

    我假设您想要进行时间插值。对于(也)空间插值,在extract中使用method = 'bilinear'

    同样,这可能行不通,因为我没有示例数据。但是这些方面的东西会起作用。

    【讨论】:

    • 谢谢@RobertH。我已修改问题以包含更多信息并更新以包含您提出的最新建议,这些建议非常有帮助。我无法让你的 {which} 函数工作,所以我改用了“findInterval”。
    • 我不确定你的函数应该如何工作。如果您尝试将 ncdf4 对象变砖,则会收到错误消息:'无法找到签名'"ncdf4"'的函数'raster'的继承方法
    • brick 应该用在文件名上,而不是用在 ncdf4 对象上
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-09-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-08-05
    相关资源
    最近更新 更多