【问题标题】:sapply for a vector of dates in Rsapply 用于 R 中的日期向量
【发布时间】:2014-09-06 15:29:13
【问题描述】:

假设 R 中有日期/时间向量:

l<-c("2011-01-01 00:00:00", "2011-01-01 01:00:00", "2011-01-01 02:00:00")

我想为这个向量的每个元素添加一定的时间(例如 1 小时)。首先,我将元素转换为 POSIXlt:

l1<-as.POSIXlt(l)

然后我尝试使用 sapply 并按照How to add/subtract time from a POSIXlt time while keeping its class in R? 中所述添加小时数:

f<-function(dt, hour){
  dt$hour<-dt$hour + hour
  return(dt)
}
sapply(l1, function(x) f(x,1))

但是,执行此代码会出现错误: dt$hour 中的错误:$ 运算符对原子向量无效

调试告诉 class(dt) 是数字而不是 POSIXt

我该如何解决这个问题?

【问题讨论】:

    标签: r datetime sapply


    【解决方案1】:

    正如您链接到的问题的答案中所说,POSIXlt 已经是一个列表。因此,您正在循环遍历 POSIXlt 列表的元素,这些元素本身没有 hour 元素。

    R> unclass(l1)
    $sec
    [1] 0 0 0
    
    $min
    [1] 0 0 0
    
    $hour
    [1] 0 1 2
    
    $mday
    [1] 1 1 1
    
    $mon
    [1] 0 0 0
    
    $year
    [1] 111 111 111
    
    $wday
    [1] 6 6 6
    
    $yday
    [1] 0 0 0
    
    $isdst
    [1] 0 0 0
    
    attr(,"tzone")
    [1] "UTC"
    

    所以你将f 应用到sec,然后是min,...,isdst

    再次,正如您在回答您链接到的问题时所说,您不应该更改POSIXlt 对象的内部元素值,并期望时间有意义。转换为POSIXct 并添加hour * 3600

    【讨论】:

      【解决方案2】:

      如果您只是在寻找一种简单的增加时间的方法,请查看包lubridate

      library(lubridate)
      ##
      Timestamps <- c("2011-01-01 00:00:00", 
                      "2011-01-01 01:00:00", "2011-01-01 02:00:00")
      dT.lt <- as.POSIXlt(
        Timestamps,
        format="%Y-%m-%d %H:%M:%S",
        tz="America/New_York")
      ##
      > dT.lt + hours(1)
      [1] "2011-01-01 01:00:00 EST" "2011-01-01 02:00:00 EST" "2011-01-01 03:00:00 EST"
      

      该软件包具有类似的实用函数,用于加/减秒、分钟、月等...,并且这些函数是矢量化的,因此您不必显式使用 *apply 函数(或者更糟的是,@ 987654324@循环)。

      【讨论】:

      • 或者,正如@Joshua Ulrich 建议的那样,转换为POSIXct 类(这是我通常使用的),并且只需使用适当的转换因子秒-> 小时。
      【解决方案3】:
      f<-function(dt = POSIXlt(), hour){
          dt$hour<-dt$hour + hour
          return(dt)
      }
      

      【讨论】:

        【解决方案4】:

        使用lubridate,使用hour&lt;- 分配功能可以轻松更改小时。

        > x <- as.POSIXlt(c("2011-01-01 00:00:00", "2011-01-01 01:00:00", 
                            "2011-01-01 02:00:00"))
        > library(lubridate)
        > hour(x) <- hour(x) + 1
        > x
        # [1] "2011-01-01 01:00:00 PST" "2011-01-01 02:00:00 PST"
        # [3] "2011-01-01 03:00:00 PST"
        

        【讨论】:

          【解决方案5】:

          要增加一小时,您必须增加 3600(60 秒乘以 60 分钟)。

          > as.POSIXlt(l) + 3600
          [1] "2011-01-01 01:00:00 CET" "2011-01-01 02:00:00 CET" "2011-01-01 03:00:00 CET"
          

          在这种情况下不需要sapply

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2015-11-21
            • 1970-01-01
            • 2021-12-18
            • 1970-01-01
            • 2016-03-24
            • 1970-01-01
            相关资源
            最近更新 更多