13

我正在使用新版本,data.table尤其是 AWESOMEfread功能。我的文件包含作为字符串加载的日期(因为我不知道该怎么做)看起来像01APR2008:09:00:00.

我需要在这些日期时间对 data.table 进行排序,然后才能有效地以IDateTime格式(或我还不知道的任何其他内容)进行排序。

> strptime("01APR2008:09:00:00","%d%b%Y:%H:%M:%S")
[1] "2008-04-01 09:00:00"

> IDateTime(strptime("01APR2008:09:00:00","%d%b%Y:%H:%M:%S"))
        idate    itime
1: 2008-04-01 09:00:00

> IDateTime("01APR2008:09:00:00","%d%b%Y:%H:%M:%S")
Error in charToDate(x) : 
character string is not in a standard unambiguous format 

看来我做不到DT[ , newType := IDateTime(strptime(oldType, "%d%b%Y:%H:%M:%S"))]

我的问题是:

  1. 有没有办法直接转换为IDateTimefrom fread,这样我就可以有效地进行排序?
  2. 如果不是,那么知道我希望能够按此日期时间列对 DT 进行排序的最有效方法是什么
4

2 回答 2

12

不幸的是(为了提高效率)strptime产生了一个 POSIXlt 类型,它不受它的支持,data.table并且总是由于它的大小(每个日期 40 字节!)和结构。尽管strftime产生了更好的 POSIXct,但它仍然通过 POSIXlt 来实现。更多信息在这里:

http://stackoverflow.com/a/12788992/403310

寻找诸如 之类的基本函数as.Date,它也使用strptime从存储为双精度的纪元(奇怪地)创建一个整数偏移量。中的IDate(和朋友)类data.table旨在实现整数时代偏移量存储为,嗯,整数。适合快速排序base::sort.list(method = "radix")(实际上是计数排序)。IDate并不是真正的目标是快速(通常是一次性)转换。

因此,为了正确或错误地转换字符串日期/时间,我倾向于推出自己的辅助函数。

如果字符串日期是"2012-12-24"我倾向于:as.integer(gsub("-", "", col))并继续使用YYYYMMDD整数日期。同样,时间可以是HHMMDD整数。两列:如果您通常希望在一天之内使用date,单独使用可能很有用,但不是前一天。按月分组简单快捷:. 添加和减去天数很麻烦,但无论如何您都不想添加日历日,而是添加工作日或工作日。因此,无论如何,这都是对您的工作日向量的查找。timeroll = TRUEby = date %/% 100L

在您的情况下,字符月份需要转换为1:12. 您的日期“01APR2008”中没有分隔符,因此 asubstring将是一种方式,后跟 a matchorfmatch在月份名称上。您可以控制文件格式吗?如果是这样,数字最好采用自然排序的明确格式,例如%Y-%m-%d, 或%Y%m%d

我还没有弄清楚如何最好地做到这一点fread,所以日期/时间目前保留为字符,因为我还不确定如何检测日期格式或输出哪种类型。它确实需要输出整数或双日期,而不是低效的字符。我怀疑我对YYYYMMDD整数的使用被视为非常规,所以我有点犹豫是否将其设为默认值。它们有自己的位置,并且基于纪元的日期也有利弊。我建议的只是日期不必总是基于时代。

你怎么看?顺便说一句,感谢您的鼓励fread;很高兴看到。

于 2012-12-28T00:27:34.700 回答
1

我不知道您的文件的结构,但从您的评论中您想使用日期字段作为键。为什么不将其作为时间序列阅读并在阅读时对其进行格式化?

这里我使用zoo来做。(这里我假设日期列是第一个,否则参见index.colum参数)

ff <- function(x) as.POSIXct(strptime(x,"%d%b%Y:%H:%M:%S"))

h <- read.zoo(text = "03avril2008:09:00:00  125
                      02avril2008:09:30:00  126
                      05avril2008:09:10:00  127
                      04avril2008:09:20:00  128
                      01avril2008:09:00:00  128"
                      ,FUN=ff)

您可以以正确的格式对日期进行排序并进行排序。

从 POSIXct 到 IDateTime 的转换很自然

    IDateTime(index(h))
        idate    itime
1: 2008-04-01 09:00:00
2: 2008-04-02 09:30:00
3: 2008-04-03 09:00:00
4: 2008-04-04 09:20:00
5: 2008-04-05 09:10:00

在这里确保您仍然进行 2 次转换,但是您在读取数据时执行此操作,而第二次您执行此操作而不处理任何格式问题。

于 2012-12-28T03:19:58.517 回答