微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何有效地将 NCDF 时间转换为适当的单位

如何解决如何有效地将 NCDF 时间转换为适当的单位

我正在尝试将 netCDF 文件中的时间单位转换为其正确格式,但是,我得到了错误输出

我使用的数据有这种格式的时间:

1 dimensions:
        time  Size:193458   *** is unlimited ***
            units: seconds since 1970-1-1 00:00:00

我已经使用包 ncdf.tools 中的函数提取时间并将其转换为日期以进行时间序列分类,但我得到了错误的结果:

convertDateNcdf2R(id_579$dim$time$vals,units="seconds")

  [75] "1846-07-03 05:04:51 UTC"
  [76] "1846-07-03 05:05:01 UTC"
  [77] "1846-07-03 05:05:06 UTC"
  [78] "1846-07-03 05:05:11 UTC"
  [79] "1846-07-03 05:05:16 UTC"

日期不应超过 1970 年。有没有更好的替代方法

创建这个的函数是:

convertDateNcdf2R  =  function(
##title<< Convert netCDF time vector to POSIXct R date object
        time.source ##<< numeric vector or netCDF connection: either a number of time units since
                    ##   origin or a netCDF file connection,In the latter case,the time 
                    ##   vector is extracted from the netCDF file,This file,and especially the 
                    ##   time variable,has to follow the CF netCDF conventions.,units = 'days' ##<< character string: units of the time source. If the source
                    ##   is a netCDF file,this value is ignored and is read from that file.,origin = as.POSIXct('1800-01-01',tz = 'UTC') ##<< POSIXct object:
                    ##   Origin or day/hour zero of the time source. If the source
                    ##   is a netCDF file,time.format =  c('%Y-%m-%d','%Y-%m-%d %H:%M:%s','%Y-%m-%d %H:%M','%Y-%m-%d %Z %H:%M','%Y-%m-%d %Z %H:%M:%s')
)
  ##description<< This function converts a time vector from a netCDF file or a vector of Julian days (or seconds,minutes,hours)
  ##              since a specified origin into a POSIXct R vector.
{
  close.file =  FALSE
  if (class(time.source) ==  'character') {
    if (file.exists(time.source)) {
      time.source = open.nc(time.source)
    } else {
      stop(paste('File ',time.source,' is not existent!',sep = ''))
    }
  }
  if (class(time.source) == 'NetCDF') {
    attget.result <- try({
      units.file      <- infoNcdfAtts(time.source,'time')[,'value'][infoNcdfAtts(time.source,'name'] == 'units']
      origin.char     <- sub('^.*since ','',units.file)
      units <-  sub(' since.*',units.file)
    },silent = TRUE)
    for (formatT in time.format) {
      origin <- strptime(origin.char,format = formatT,tz =  'UTC')
      if (!is.na(origin))
        break
    }
    if (is.na(origin))
      stop('Not possible to determine origin. Wrong format supplied?')

    date.vec     <- as.numeric(var.get.nc(time.source,'time')) 
  } else {
    if (!is.numeric(time.source))
      stop('time.source needs to be numeric if not a netCDF file connection!')
    date.vec  <- time.source
  }

  
  if (!is.element(units,c('seconds','minutes','hours','days')))
    stop(paste('Unit ',units,' is not implemented.',sep  =  ''))
  multiplicator      <- switch(units,days = 60 * 60 * 24,hours = 60 * 60,minutes = 60,seconds = 1)
  time.out <- origin + date.vec * multiplicator
  if (origin <  as.POSIXct('1582-10-30',tz = 'UTC')) 
    time.out <- time.out + 10 * 24 * 60 * 60
  if (close.file)
    close.nc(time.source)
  ##value<<
  ## POSIXct vector: time vector in native R format
  return(time.out)
}

以下是时间数据的一些示例:

        time
1 1467435408
2 1467435418
3 1467435425
4 1467435431
5 1467435438
6 1467435444

解决方法

我在使用不同类型的日历时遇到了类似的问题,但在我发现 ncdf4.helpers 包后,现在一切都变得更加轻松快捷。一个例子:

 > library(ncdf4)
 > #open the netcdf file 
 > ncin<- nc_open("precip_GPCP_1998.nc")

 > library(ncdf4.helpers)
 > #obtain time dimension in date format
 > Time_in_Date_format <- nc.get.time.series(f = ncin,time.dim.name = "time")

 > nc_close(ncin)

 > Time_in_Date_format
 [1] "1998-01-01" "1998-02-01" "1998-03-01" "1998-04-01" "1998-05-01"
 [6] "1998-06-01" "1998-07-01" "1998-08-01" "1998-09-01" "1998-10-01"
 [11] "1998-11-01" "1998-12-01"

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。