0

data.table 1.9.6 throws an error when you try to assign a POSIXlt date to a column

ex:

dt <- data.table(strdate = c("20140101", "20140103"))
dt[, date := strptime(strdate, "%Y%m%d")]
Warning message:
  In `[.data.table`(dt, , `:=`(date, strptime(strdate, "%Y%m%d"))) :
  Supplied 11 items to be assigned to 2 items of column 'date' (9 unused)

dt
    strdate date
1: 20140101  0,0
2: 20140103  0,0

However, a data frame works

df <- as.data.frame(dt)
df$date <- strptime(df$strdate, "%Y%m%d")
df
   strdate       date
1 20140101 2014-01-01
2 20140103 2014-01-03

Is there something about data.table that makes it unable to handle this data type?

Allen Wang
  • 2,426
  • 2
  • 24
  • 48
  • 3
    Take a look at `unclass(strptime(dt$strdate, "%Y%m%d"))` - `POSIXlt` is actually a list object. Also see - http://stackoverflow.com/questions/21487614/error-creating-r-data-table-with-date-time-posixlt – thelatemail Nov 14 '16 at 23:00
  • 2
    This is documented. Just use `POSIXct` instead. `data.table` has fine converters as `as.IDate()` and `as.ITime()`. See the answer I just added. – Dirk Eddelbuettel Nov 14 '16 at 23:12

2 Answers2

3

Just use POSIXct which you, inter alia, get for free from the anytime package.

R> dt <- data.table(strdate = c("20140101", "20140103"))
R> dt
    strdate
1: 20140101
2: 20140103
R> library(anytime)
R> dt[, date := anytime(strdate)]   # creates POSIXct, use anydate() for Date
R> dt
    strdate       date
1: 20140101 2014-01-01
2: 20140103 2014-01-03
R> 

The column now contains proper date(time) representation which you can still compute on:

R> dt[, newdate := as.IDate(date) + 7]
R> dt
    strdate       date    newdate
1: 20140101 2014-01-01 2014-01-08
2: 20140103 2014-01-03 2014-01-10
R> 

Or, if you want dates, just use the Date type, eg via anydate():

R> dt <- data.table(strdate = c("20140101", "20140103"))
R> dt[, date := anydate(strdate)]
R> dt[, newdate := date + 7]
R> dt
    strdate       date    newdate
1: 20140101 2014-01-01 2014-01-08
2: 20140103 2014-01-03 2014-01-10
R> 
Dirk Eddelbuettel
  • 360,940
  • 56
  • 644
  • 725
1

Here's a workaround using lubridate:

dt$date <- as.POSIXct(lubridate::ymd(strptime(dt$strdate, "%Y%m%d")))
    strdate       date
1: 20140101 2014-01-01
2: 20140103 2014-01-03

Please also see this post on why we use POSIXct instead of POSIXlt with data.table.

Community
  • 1
  • 1
Hack-R
  • 22,422
  • 14
  • 75
  • 131