2

I need to append a datetime object to my POSIXct element. Some sampledata:

my_chr<-c('2017-02-19 06:00','2017-03-10 06:00','2017-04-15 06:00')
myPSX<-as.POSIXct(my_chr,format='%Y-%m-%d %H:%M',tz='UTC')
PSXappend<-as.POSIXct('2017-08-09 06:00',format='%Y-%m-%d %H:%M',tz='UTC')

But somehow if I try c() it changes the timezone. If i try to coerce it together with as.POSIXct it drops the datetime object I need to append.

5th
  • 2,097
  • 3
  • 22
  • 41
  • See `?POSIXct`: "Using `c` on `POSIXlt` objects converts them to the current time zone, and on `POSIXct` objects drops any `tzone` attributes (even if they are all marked with the same time zone)." Related: [Guard against accidental time-zone conversion](https://stackoverflow.com/questions/7665605/guard-against-accidental-time-zone-conversion) – Henrik Mar 15 '18 at 21:50
  • Yeah the surprise to me is that `POSIX` doesn't behave like any other R-object. Any idea why? Is it because `POSIX` is sort of a system.time-object? – 5th Mar 15 '18 at 21:55

2 Answers2

3

In this case you could append a value by indexing, which will neither change the time zone nor the class of myPSX:

myPSX[length(myPSX) + 1] <- PSXappend
Daniel
  • 2,207
  • 1
  • 11
  • 15
  • Suppose that is the only way of appending it right? Just out of curiousity – 5th Mar 15 '18 at 21:56
  • you could also use `c()` and then manually change the time zone back by using `with_tz` in the package `lubridate::with_tz(c(myPSX, PSXappend), "UTC")` – Daniel Mar 15 '18 at 22:03
0

Since I have to run this on quite a large dataset, I ran some benchmarks to compare the different possibilities. Actually @Dan's solution is quite fast. However using attr(dttm,'tzone')<-'UTC' is slightly faster.

myfun1<-function(){
myPSX[length(myPSX) + 1] <- PSXappend
}

myfun2<-function(){
dttm<-c(myPSX,PSXappend)
attr(dttm,'tzone')<-'UTC'
}

library(lubridate)
myfun3<-function(){
dttm<-c(myPSX,PSXappend)
with_tz(dttm, "UTC")
}

myfun4<-function(){
dttm<-as.POSIXct(c(my_chr,'2017-08-09 06:00'),format='%Y-%m-%d %H:%M',tz='UTC')
}

microbenchmark::microbenchmark(myfun1(),myfun2(),myfun3(),myfun4())
Unit: microseconds
     expr    min     lq      mean  median      uq      max neval
 myfun1() 12.642 15.210  17.92005 16.9875 17.7780   59.654   100
 myfun2() 11.852 13.827  16.39909 14.4200 15.8025   43.062   100
 myfun3() 26.864 29.432 121.86874 30.8150 33.1850 5852.844   100
 myfun4() 31.605 34.766  61.66142 36.3460 40.2970 2182.323   100
5th
  • 2,097
  • 3
  • 22
  • 41