【问题标题】:Convert data.table string column to POSIXct; round.POSIXt() returns a POSIXlt?将 data.table 字符串列转换为 POSIXct; round.POSIXt() 返回一个 POSIXlt?
【发布时间】:2016-08-29 04:24:22
【问题描述】:

我有一个日期时间列作为字符存储在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() 应该可以工作。

感谢您的任何想法。

【问题讨论】:

  • 至 POSIXct:dat[, my_date := as.POSIXct(date_chr, format = "%Y-%m-%d %I:%M")],仅限日期:dat[, date_only := as.Date(my_date, tz = "Australia/Melbourne")]
  • 当你使用round.POSIXt()时,它会返回一个列表(见?round.POSIXt),即POSIXlt对象。
  • data.table 出于性能原因不支持POSIXlt types
  • @arvi1000 我已经扩展了答案以澄清在 data.table 中存储 POSIXlt 仍然是可能的,只是与在 data.frame 中的方式不同。

标签: r data.table lubridate posixct datetime-conversion


【解决方案1】:

@SymbolixAU 在 cmets 中已经很好地回答了。
解决您关于 data.frame/data.frame 差异的问题。
主要区别在于POSIXltPOSIXct 占用更多内存,而data.table 确实关心内存。

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

重要的是,您仍然可以在 data.table j 参数中使用 POSIXlt 数据类型(及其方法),只需确保在分配给列时将其转换为 POSIXct

如果出于某种原因您想将 POSIXlt 存储在 data.table 中...data.table 不支持与 data.frame 相同的 POSIXlt 类型。您可以将 POSIXlt 存储在 data.table 中,但只需将其包装到列表中,就像任何其他非原子数据类型一样。

【讨论】:

  • 谢谢。接受这个答案,但您可以编辑添加“data.table 不支持 POSIXlt 类型”,以便在后代中获得最大清晰度
【解决方案2】:

类似的东西

data.table(as.Date(date_chr))

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-10-21
    • 1970-01-01
    • 2011-01-28
    • 2013-07-21
    • 1970-01-01
    • 2012-05-28
    • 1970-01-01
    相关资源
    最近更新 更多