How to make an empty vector of POSIXct

后端 未结 6 1311
孤街浪徒
孤街浪徒 2021-02-12 03:21

I want to make an empty vector of POSIXct so that I can put a POSIXct in it:

vec <- vector(\"POSIXct\", 10)
vec
vec[1] <- \"2014-         


        
相关标签:
6条回答
  • 2021-02-12 04:06

    I would go for Gregor's solution. I first went with Rich Scriven's solution but then got an error when I tried to compute the difference for a Non-NA element later as shown in the example below

    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
    

    This can even lead to strange bugs like this one which can take a while to discover

    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
    
    0 讨论(0)
  • 2021-02-12 04:09

    When creating a POSIXct vector in the following way, the underlying type becomes 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)
    

    Combining the above vector with an empty vector of POSIXct initialized with character as the underlying type, results in a character-POSIXct vector:

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

    ... which cannot be plotted directly:

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

    I therefore prefer initializing my empty POSIXct vectors with double or integer as the underlying type:

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

    When using double, the vector is also initialized with valid dates (which might or might not be preferable):

    > .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"
    
    0 讨论(0)
  • 2021-02-12 04:16

    Since there is no POSIX mode, you cannot initialize a POSIXct vector with vector() alone (see ?mode for a list of all mode types).

    But we can use .POSIXct to create the vector from a character vector.

    (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" 
    

    Also note that you can also use .POSIXct(integer(10)) for a length 10 vector of origin date-times.

    0 讨论(0)
  • 2021-02-12 04:19

    Perhaps I missed it above, but this is a truly empty POSIXct:

    as.POSIXct(integer())
    

    For example, if you want an empty data frame:

    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) 
    
    0 讨论(0)
  • 2021-02-12 04:22

    I usually initialize things to NA:

    as.POSIXct(rep(NA, 10))
    

    works well in this case. It's explicitly doing what happens under-the-hood in @RichardScriven's answer---see the comments there for a longer discussion.

    0 讨论(0)
  • 2021-02-12 04:22

    I use the following function for this. Very similar to the other solutions.

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

    So you can do things like this.

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

    This can also be done with lubridate.

    library(lubridate)
    
    > as_datetime(integer(0))
    POSIXct of length 0
    
    0 讨论(0)
提交回复
热议问题