【问题标题】:Round time by X hours in R?R中的X小时循环时间?
【发布时间】:2017-07-18 16:24:59
【问题描述】:

在对时间戳数据进行预测建模时,我想在 R 中编写一个函数(可能使用 data.table),将日期四舍五入 X 小时数。例如。四舍五入 2 小时应给出:

"2014-12-28 22:59:00 EDT" becomes "2014-12-28 22:00:00 EDT" 
"2014-12-28 23:01:00 EDT" becomes "2014-12-29 00:00:00 EDT" 

当您舍入 1 小时时,这很容易做到 - 使用 round.POSIXt(.date, "hour") 函数。
然而,编写一个通用函数,就像我在下面使用多个 if 语句所做的那样,变得非常难看:

d7.dateRoundByHour <- function (.date, byHours) { 

  if (byHours == 1)
    return (round.POSIXt(.date, "hour"))

  hh = hour(.date); dd = mday(.date); mm = month(.date); yy = year(.date)    
  hh = round(hh/byHours,digits=0) * byHours
  if (hh>=24) { 
    hh=0; dd=dd+1 
  }
  if ((mm==2 & dd==28) | 
      (mm %in% c(1,3,5,7,8,10,12) & dd==31) | 
      (mm %in% c(2,4,6,9,11) & dd==30)) {  # NB: it won't work on 29 Feb leap year. 
    dd=1; mm=mm+1
  }
  if (mm==13) {
    mm=1; yy=yy+1
  }
  str = sprintf("%i-%02.0f-%02.0f %02.0f:%02.0f:%02.0f EDT", yy,mm,dd, hh,0,0)
  as.POSIXct(str, format="%Y-%m-%d %H:%M:%S") 
}

谁能展示一个更好的方法来做到这一点?
(也许通过转换为数字并返回到 POSIXt 或其他一些 POSIXt 函数?)

【问题讨论】:

  • highfrequency 有一个名为 aggregatets() 的包装器,它应该会给你想要的结果

标签: r date data.table posixct


【解决方案1】:

使用 lubridate 包中的 round_date 函数。假设您有一个 data.table,其中包含一个名为 date 的列,您可以执行以下操作:

dt[, date := round_date(date, '2 hours')]

一个简单的例子会给你你正在寻找的结果:

x <- as.POSIXct("2014-12-28 22:59:00 EDT")
round_date(x, '2 hours')

【讨论】:

    【解决方案2】:

    这实际上非常简单,只需要基本 R。你的“奇数”循环的基本思想

    • 按适当的比例因子缩小
    • 以缩小的单位向下舍入为整数
    • 扩展备份并重新转换

    或者在两个 R 代码语句中:

    R> pt <- as.POSIXct(c("2014-12-28 22:59:00", "2014-12-28 23:01:00 EDT"))
    R> pt   # just to check
    [1] "2014-12-28 22:59:00 CST" "2014-12-28 23:01:00 CST"
    R> 
    R> scalefactor <- 60*60*2   # 2 hours of 60 minutes times 60 seconds
    R> 
    R> as.POSIXct(round(as.numeric(pt)/scalefactor) * scalefactor, origin="1970-01-01")
    [1] "2014-12-28 22:00:00 CST" "2014-12-29 00:00:00 CST"
    R> 
    

    最后一行的关键就是我所概述的:将POSIXct 转换为数字表示,按比例缩小,然后四舍五入,然后再按比例放大并再次转换为POSIXct

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-02-22
      • 1970-01-01
      • 2019-06-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-09-25
      相关资源
      最近更新 更多