Преобразование строкового столбца data.table в POSIXct; round.POSIXt() возвращает POSIXlt?

У меня есть столбец даты и времени, хранящийся как символ в файле data.table. Когда я конвертирую в POSIXct, а затем пытаюсь округлить до даты, я получаю странные результаты.

library(data.table)
library(lubridate)

# suppose I have these dates, in a data.table
date_chr <- c("2014-04-09 8:37 AM", "2014-09-16 6:04 PM", 
              "2014-09-30 3:26 PM", "2014-11-13 12:47 PM",
              "2014-11-05 12:25 PM")
dat <- data.table(date_chr)

# I convert to POSIXct...
dat[, my_date := ymd_hm(date_chr)]

# ...and I want to round to date only, but this doesn't work
dat[, date_only := round(my_date, 'days')] # why does this return a list?
dat[, date_only := trunc(my_date, 'days')] # this too

class(dat$date_only) это list, и я получаю это предупреждающее сообщение

# Warning message:
#   In `[.data.table`(dat, , `:=`(date_only, round(my_date, "days"))) :
#   Supplied 9 items to be assigned to 5 items of column 'date_only' (4 unused)

Между тем, это работает отлично!

dat_df <- data.frame(date_chr, stringsAsFactors = F)
dat_df$my_date <- ymd_hm(dat_df$date_chr)
dat_df$date_only <- round(dat_df$my_date, 'days')

class(dat_df$date_only) равно POSIXlt, POSIXt, как хотелось бы.

Мой вопрос в том, почему это и как я могу избежать проблемы при использовании data.table? Есть обходные пути, такие как усечение временной части date_chr перед преобразованием, но похоже, что round.POSIXt() должно работать.

Спасибо за любые мысли.


person arvi1000    schedule 29.08.2016    source источник
comment
Для POSIXct: dat[, my_date := as.POSIXct(date_chr, format = "%Y-%m-%d %I:%M")], и только для даты: dat[, date_only := as.Date(my_date, tz = "Australia/Melbourne")]   -  person SymbolixAU    schedule 29.08.2016
comment
Когда вы используете round.POSIXt(), он возвращает список (см. ?round.POSIXt), т. е. объект POSIXlt.   -  person SymbolixAU    schedule 29.08.2016
comment
Взгляните на r документацию по датам.   -  person SymbolixAU    schedule 29.08.2016
comment
Да, но мне интересно, почему существует большая разница между контекстами data.table и data.frame. dat_df$date_only <- round(dat_df$my_date, 'days') приводит к созданию одного нового столбца класса POSIXt, а версия data.table — нет.   -  person arvi1000    schedule 29.08.2016
comment
data.table не поддерживает типы POSIXlt по соображениям производительности.   -  person SymbolixAU    schedule 29.08.2016
comment
Ах. data.table не поддерживает типы POSIXlt - это ответ, который я ищу. Спасибо   -  person arvi1000    schedule 29.08.2016
comment
@arvi1000 arvi1000 Я расширил ответ, чтобы уточнить, что сохранение POSIXlt в data.table все еще возможно, но не так, как в data.frame.   -  person jangorecki    schedule 29.08.2016
comment
Пожалуйста; Я знал, что вскоре появится более знающий data.tableer, чтобы расширить и дать более подробную информацию в ответе.   -  person SymbolixAU    schedule 30.08.2016


Ответы (2)


@SymbolixAU уже довольно хорошо ответил в комментариях.
Отвечая на ваш вопрос о разнице между data.frame/data.frame в этом отношении.
Основное отличие заключается в том, что POSIXlt занимает гораздо больше памяти, чем POSIXct, и данных. таблица заботится о памяти.

object.size(Sys.time())
#312 bytes
object.size(as.POSIXlt(Sys.time()))
#2144 bytes

Important to know is that you can still use POSIXlt data type (and its methods) in data.table j argument, just make sure to convert it to POSIXct when assigning to a column.

Если по какой-то причине вы хотите сохранить POSIXlt в data.table... data.table не поддерживает тип POSIXlt так же, как data.frame. Вы можете хранить POSIXlt в data.table, но просто обернуть его в список, как и любой другой неатомарный тип данных.

person jangorecki    schedule 29.08.2016
comment
Спасибо. Принятие этого ответа, но вы можете отредактировать, чтобы добавить data.table не поддерживает типы POSIXlt для максимальной ясности в потомстве - person arvi1000; 29.08.2016

и что-то вроде

data.table(as.Date(date_chr))
person fidelin    schedule 21.05.2018