【问题标题】:How to make an empty vector of POSIXct如何制作POSIXct的空向量
【发布时间】:2014-11-21 00:25:17
【问题描述】:

我想创建一个POSIXct 的空向量,以便我可以在其中放入一个POSIXct

vec <- vector("POSIXct", 10)
vec
vec[1] <- "2014-10-27 18:11:36 PDT"
vec

那行不通。有什么想法吗?

【问题讨论】:

  • 我喜欢初始化为NA, as.POSIXct(rep(NA, 10))
  • @Gregor - 你想把它作为答案发布吗?关于结果的数学运算,我有一些合理的担忧。

标签: r posixct


【解决方案1】:

由于没有 POSIX mode,因此您不能单独使用 vector() 初始化 POSIXct 向量(有关所有模式类型的列表,请参见 ?mode)。

但我们可以使用.POSIXct 从字符向量创建向量。

(x <- .POSIXct(character(10))) ## the same as .POSIXct(vector("character", 10))
# [1] NA NA NA NA NA NA NA NA NA NA
class(x)
# [1] "POSIXct" "POSIXt" 

还请注意,您还可以使用 .POSIXct(integer(10)) 来表示长度为 10 的原始日期时间向量。

【讨论】:

  • 这是我以前从未尝试过的。有趣的! +1
  • 这很简洁,但它依赖于.POSIXct 中的解析失败。 .POSIXct(rep(NA, 10)) 更简单(也可能更清晰)
  • 解析失败?不确定这意味着什么,.POSIXct() 只是使用structure()。有很多方法。你也可以.POSIXct(NA[1:10])
  • 通过解析 fallthrough 我的意思是 character(10) 生成一个包含 10 个空字符串的向量,而不是 10 个 NA,因此生成的结构有效,因为 "" 打印为 NA。 rep 解决方案生成一个逻辑向量,该向量将被提升为数字。这意味着像x + 3600 这样的操作会给出奇怪的错误。
  • 对于未来的观众,我会注意到我确实包含了.POSIXct(integer(10)),尽管答案中没有明确说明,但它可以用于数学运算。
【解决方案2】:

我通常将事物初始化为NA

as.POSIXct(rep(NA, 10))

在这种情况下效果很好。它明确地做了@RichardScriven 的回答中发生的事情——请参阅那里的 cmets 进行更长时间的讨论。

【讨论】:

    【解决方案3】:

    这个问题现在有了一个非常简单的答案!

    lubridate 允许您简单地编写,例如,empty_df &lt;- tibble(date = POSIXct())

    【讨论】:

      【解决方案4】:

      我会选择Gregor's solution。我首先使用Rich Scriven's solution,但后来在尝试计算非NA 元素的差异时出现错误,如下例所示

      t1 <- as.POSIXct("2014-10-27 18:11:36 PDT")
      t2 <- as.POSIXct("2014-11-20 18:11:36 PDT")
      x <- .POSIXct(character(10))
      x[1] <- t1
      
      difftime(t2, t1)
      #R Time difference of 24 days
      
      # fails
      difftime(t2, x[1])
      #R Error in unclass(time1) - unclass(time2) : 
      #R   non-numeric argument to binary operator
      
      unclass(x[1]) # character
      #R [1] "1414429896"
      unclass(t1)
      #R [1] 1414429896
      #R attr(,"tzone")
      #R [1] ""
      
      x <- .POSIXct(rep(NA_real_, 10))
      x[1] <- t1
      difftime(t2, x[1]) # all good
      #R Time difference of 24 days
      

      这甚至会导致像这样的奇怪错误,需要一段时间才能发现

      t1 <- as.POSIXct("2001-07-24 CEST")
      t2 <- as.POSIXct("2002-08-29 CEST")
      x <- .POSIXct(character(10))
      x[1] <- t1
      
      t2 < t1
      #R [1] FALSE
      t2 < x[1] # oh boy 
      #R [1] TRUE
      
      # the reason (I think)
      unclass(t2)
      #R [1] 1030572000
      #R attr(,"tzone")
      #R [1] ""
      unclass(x[1])
      #R [1] "995925600"
      
      "995925600" > 1030572000
      #R [1] TRUE
      

      【讨论】:

        【解决方案5】:

        当以如下方式创建POSIXct向量时,底层类型变为double:

        > times <- as.POSIXct(c("2015-09-18 09:01:05.984 CEST", "2015-09-18 10:01:10.984 CEST", "2015-09-18 10:21:20.584 CEST"))
        > typeof(times)
        [1] "double"
        > values <- c(5,6,7)
        

        将上述向量与以字符为基础类型初始化的 POSIXct 空向量相结合,得到一个字符 POSIXct 向量:

        > tm1 <- c(.POSIXct(character(0)), times)
        > typeof(tm1)
        [1] "character"
        

        ...不能直接绘制:

        > ggplot() + geom_line(aes(x=tm1, y=val), data=data.frame(tm1,val))
        geom_path: Each group consist of only one observation. Do you need to adjust the group aesthetic?
        

        因此,我更喜欢使用双精度或整数作为基础类型来初始化我的空 POSIXct 向量:

        > tm2 <- c(.POSIXct(double(0)), times)
        > typeof(tm2)
        [1] "double"
        > ggplot() + geom_line(aes(x=tm2, y=val), data=data.frame(tm2,val))
        

        > tm3 <- c(.POSIXct(integer(0)), times)
        > typeof(tm3)
        [1] "double"
        > ggplot() + geom_line(aes(x=tm3, y=val), data=data.frame(tm3,val))
        #Same thing...
        

        当使用双精度时,向量也被初始化为有效日期(这可能会或可能不会更可取):

        > .POSIXct(character(10))
         [1] NA NA NA NA NA NA NA NA NA NA
        > .POSIXct(double(10))
         [1] "1970-01-01 01:00:00 CET" "1970-01-01 01:00:00 CET" "1970-01-01 01:00:00 CET" "1970-01-01 01:00:00 CET" "1970-01-01 01:00:00 CET" "1970-01-01 01:00:00 CET"
         [7] "1970-01-01 01:00:00 CET" "1970-01-01 01:00:00 CET" "1970-01-01 01:00:00 CET" "1970-01-01 01:00:00 CET"
        

        【讨论】:

          【解决方案6】:

          我为此使用以下函数。与其他解决方案非常相似。

          vector_datetime <- function(n = 0L) structure(rep(NA_integer_, n), class = c("POSIXct", "POSIXt"))
          

          所以你可以做这样的事情。

          > vector_datetime()
          POSIXct of length 0
          
          > vector_datetime(10)
           [1] NA NA NA NA NA NA NA NA NA NA
          
          > class(vector_datetime(10))
          [1] "POSIXct" "POSIXt" 
          

          这也可以通过lubridate 完成。

          library(lubridate)
          
          > as_datetime(integer(0))
          POSIXct of length 0
          

          【讨论】:

            【解决方案7】:

            也许我在上面错过了它,但这是一个真正的空 POSIXct:

            as.POSIXct(integer())
            

            例如,如果你想要一个空的数据框:

            empty <- data.frame(date_time = as.POSIXct(integer()),
                                date = as.Date(x = integer(), origin = "1970-01-01"))
            empty
            [1] date_time date     
            <0 rows> (or 0-length row.names)
            
            str(empty)
            'data.frame':   0 obs. of  2 variables:
             $ date_time: 'POSIXct' num(0) 
             - attr(*, "tzone")= chr ""
             $ date     : 'Date' num(0) 
            

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 2011-01-29
              • 1970-01-01
              • 2021-12-25
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2022-01-15
              相关资源
              最近更新 更多