Search code examples
rposixct

Subsetting POSIXct, losing timezone


Please see the R below. I'm subsetting from a larger time series (which var dt1 is representative of) and the timezone is getting dropped. Any suggestions?

> dt1 <- as.POSIXct("2011-07-01 13:42:00", tz="America/New_York")
> dt1
[1] "2011-07-01 13:42:00 EDT"

> attr(dt1,"tzone")
[1] "America/New_York"

> df <- data.frame(subsetDate=.POSIXct(character(3)), otherData=numeric(3))

> df$subsetDate[1] <- dt1
df
       subsetDate otherData
1 2011-07-01 13:42:00         0
2                <NA>         0
3                <NA>         0

> attr(df$subsetDate[1],"tzone")
NULL

The other problem, besides dropping the tz, is that while the result is still identified str() as POSIXct, I can no longer do math on those dates.

> str(df$subsetDate)
POSIXct[1:5], format: "2011-07-01 13:42:00" NA NA 

> df$subsetDate[1]+3600
Error in unclass(e1) + unclass(e2) : 
non-numeric argument to binary operator

Solution

  • You have a couple of problems:

    1. Using .POSIXct instead of as.POSIXct is a bad idea; it is an internal function not intended to be available; among other things, it doesn't actually convert the internal representation of the date to numeric the way as.POSIXct does (this is why math doesn't work).
    2. [<- drops attributes

    To resolve 1, use:

    df <- data.frame(subsetDate=as.POSIXct(NA_character_, format=""), otherData=numeric(3))
    

    Math will work on the above table:

    > df$subsetDate[1] <- dt1
    > df
               subsetDate otherData
    1 2011-07-01 13:42:00         0
    2                <NA>         0
    3                <NA>         0
    > df[1] + 3600
               subsetDate
    1 2011-07-01 14:42:00
    3                <NA>    
    2                <NA>
    

    For the second point, attribute copying rules are a not always super intuitive, and [<- has the tendency to drop attributes. After all, it isn't always clear whether you want the attributes from the LHS or the RHS. For your specific problem, you can just set the attributes the way @BondedDust suggests