直接将字符串转换为IDateTime

时间:2012-12-27 14:37:22

标签: r datetime data.table

我正在使用data.table的新版本,特别是AWESOME fread函数。我的文件包含作为字符串加载的日期(因为我不知道这样做),看起来像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. 有没有办法从IDateTime直接投射到fread,以便我可以有效地排序?
  2. 如果没有,知道我希望能够通过此日期时间列对DT进行排序,最有效的方法是什么

2 个答案:

答案 0 :(得分:11)

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

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

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

所以要正确或错误地转换字符串日期/时间,我倾向于推出自己的帮助函数。

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

在您的情况下,角色月份需要转换为1:12。您的日期“01APR2008”中没有分隔符,因此substring将是一种方式,后面是月份名称上的matchfmatch。你在控制文件格式吗?如果是这样,数字会以明确的格式更好地自然排序,例如%Y-%m-%d%Y%m%d

我还没有在fread中做得最好,所以日期/时间目前仍然是字符,因为我还不确定如何检测日期格式或输出哪种类型。它确实需要输出整数或双日期,而不是低效的字符。我怀疑我对YYYYMMDD整数的使用被认为是非常规的,所以我有点犹豫要不要将它作为默认值。他们有自己的位置,也有基于时代的日期的利弊。根据我的建议,日期 总是以纪元为基础。

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

答案 1 :(得分: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次转换,但是你在读取数据时会这样做,而第二次是在没有处理任何格式问题的情况下进行转换。