将Google财经库存数据中的时间戳转换为正确的日期时间

时间:2017-08-26 17:18:04

标签: r datetime split data.table unix-timestamp

我正在尝试将库存数据中的时间戳从Google财经API转换为更实用的日期时间格式。

我使用data.table::fread来阅读数据here

fread(<url>)

      datetime    open     high      low    close  volume
1: a1497619800 154.230 154.2300 154.2300 154.2300     500
2:           1 153.720 154.3200 153.7000 154.2500 1085946
3:           2 153.510 153.8000 153.2000 153.7700   34882
4:           3 153.239 153.4800 153.1400 153.4800   24343
5:           4 153.250 153.3000 152.9676 153.2700   20212

正如您所看到的,&#34; datetime&#34;格式很奇怪。格式在此link中描述:

  

完整的时间戳由前导&#39; a表示。像这样:a1092945600。 &#39; a&#39;之后的数字是一个Unix时间戳。 [...]

     

没有领先&#39; a&#39;是&#34;间隔&#34;。因此,例如,下面数据集中的第二行的间隔为1.您可以将此数字乘以我们的间隔大小[...]并将其添加到上一个Unix时间戳。

就我而言,&#34;间隔大小&#34;是300秒(5分钟)。这种格式在每个新的一天开始时重新开始,因此尝试格式化是非常困难的!

我可以使用grep并搜索&#34; a&#34;;

来提取当天开始的索引位置
newDay <- grep(df$V1, pattern = "a") 

然后我的想法是根据索引位置将数据帧拆分为块,然后分别在每天延长unix时间,然后在存储之前将它们组合回data.table。

data.table::split看起来它会完成这项工作,但我不确定如何通过索引位置分配日间休息时间,或者是否有更合理的方法来实现相同的结果而不必把它分解成每一天。

感谢。

2 个答案:

答案 0 :(得分:4)

您可以使用grepl在“datetime”中搜索"a",这会产生一个布尔矢量。 cumsum布尔值来创建分组变量 - 对于每个"a"TRUE),计数器将增加1。

在每个组中,使用适当的POSIXctformat(以及时区,origin?)将第一个元素转换为tz。添加“间隔大小”(300秒)的倍数,第一个元素使用零,其他元素使用“日期时间”倍数。

d[ , time := {
  t1 <- as.POSIXct(datetime[1], format = "a%s", origin = "1970-01-01")
  .(t1 + c(0, as.numeric(datetime[-1]) * 300))
}
, by = .(cumsum(grepl("^a", datetime)))]

d
#       datetime                time
# 1: a1497619800 2017-06-16 15:30:00
# 2:           1 2017-06-16 15:35:00
# 3:           2 2017-06-16 15:40:00
# 4:           3 2017-06-16 15:45:00
# 5:           4 2017-06-16 15:50:00
# 6: a1500000000 2017-07-14 04:40:00
# 7:           3 2017-07-14 04:55:00
# 8:           5 2017-07-14 05:05:00
# 9:           7 2017-07-14 05:15:00

一些玩具数据:

d <- fread(input = "datetime    
a1497619800 
          1 
          2 
           3 
           4
a1500000000
3
5
7") 

答案 1 :(得分:1)

使用:

DT[grep('^a', date), datetime := as.integer(gsub('\\D+','',date))
   ][, datetime := zoo::na.locf(datetime)
     ][nchar(date) < 4, datetime := datetime + (300 * as.integer(date))
       ][, datetime := as.POSIXct(datetime, origin = '1970-01-01', tz = 'America/New_York')][]

你得到:

             date  close     high    low     open volume            datetime
   1: a1500298200 153.57 153.7100 153.57 153.5900   1473 2017-07-17 09:30:00
   2:           1 153.51 153.8700 153.33 153.7500 205057 2017-07-17 09:35:00
   3:           2 153.49 153.7800 153.34 153.5800  70023 2017-07-17 09:40:00
   4:           3 153.68 153.7300 153.42 153.5400  53050 2017-07-17 09:45:00
   5:           4 153.06 153.7500 153.06 153.7200 120899 2017-07-17 09:50:00
  ---                                                                       
2348:         937 143.94 144.0052 143.91 143.9917  36651 2017-08-25 15:40:00
2349:         938 143.90 143.9958 143.90 143.9400  40769 2017-08-25 15:45:00
2350:         939 143.94 143.9500 143.87 143.8900  56616 2017-08-25 15:50:00
2351:         940 143.97 143.9700 143.89 143.9400  56381 2017-08-25 15:55:00
2352:         941 143.74 143.9700 143.74 143.9655 179811 2017-08-25 16:00:00

使用过的数据:

DT <- fread('https://www.google.com/finance/getprices?i=300&p=30d&f=d,t,o,h,l,c,v&df=cpct&q=IBM', skip = 7, header = FALSE)
setnames(DT, 1:6, c('date','close','high','low','open','volume'))