alexperrone
alexperrone

Reputation: 667

Rounding POSIXct in data.table

Using the same data from this question, there is a problem with rounding date-times to the second in data.table v1.9.2.

require(data.table)
options(digits.secs=3)  # usually placed in .Rprofile
DT <- data.table(timestamp=c(as.POSIXct("2013-01-01 17:51:00.707"),
                             as.POSIXct("2013-01-01 17:51:59.996"),
                             as.POSIXct("2013-01-01 17:52:00.059"),
                             as.POSIXct("2013-01-01 17:54:23.901"),
                             as.POSIXct("2013-01-01 17:54:23.914")))
DT
DT[ , round(timestamp)]  # looks good
DT[ , timestamp_rounded := round(timestamp)]  # does not work
DT[ , timestamp_rounded := round(timestamp, units="secs")]  # does not work
DT
#                   timestamp timestamp_rounded
# 1: 2013-01-01 17:51:00.707       1,0,0,24,24
# 2: 2013-01-01 17:51:59.996    51,52,52,54,54
# 3: 2013-01-01 17:52:00.059    17,17,17,17,17
# 4: 2013-01-01 17:54:23.901         1,1,1,1,1
# 5: 2013-01-01 17:54:23.914         0,0,0,0,0

I found a solution using lubridate:

require(lubridate)
DT[ , timestamp_rounded := round_date(timestamp, "second")]  # works

Is there a data.table approach?

Upvotes: 2

Views: 721

Answers (1)

eddi
eddi

Reputation: 49448

round.POSIXt produces POSIXlt objects and data.table (intentionally) does not store POSIXlt objects, because they are unnecessarily large. The solution is then to simply convert back to POSIXct:

DT[, timestamp_rounded := as.POSIXct(round(timestamp))]
#                 timestamp   timestamp_rounded
#1: 2013-01-01 17:51:00.707 2013-01-01 17:51:01
#2: 2013-01-01 17:51:59.996 2013-01-01 17:52:00
#3: 2013-01-01 17:52:00.059 2013-01-01 17:52:00
#4: 2013-01-01 17:54:23.901 2013-01-01 17:54:24
#5: 2013-01-01 17:54:23.914 2013-01-01 17:54:24

Upvotes: 6

Related Questions