【问题标题】:Convert timestamps in Google Finance stock data to proper datetime将 Google Finance 股票数据中的时间戳转换为正确的日期时间
【发布时间】:2017-08-26 17:18:03
【问题描述】:

我正在尝试将来自 Google Finance 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

如您所见,“日期时间”格式相当奇怪。格式在这个link中描述:

完整的时间戳由前导“a”表示。像这样:a1092945600。 'a' 后面的数字是 Unix 时间戳。 [...]

没有前导“a”的数字是“间隔”。因此,例如,下面数据集中的第二行的间隔为 1。您可以将此数字乘以我们的间隔大小 [...] 并将其添加到最后一个 Unix 时间戳。

在我的例子中,“间隔大小”是 300 秒(5 分钟)。这种格式在每个新的一天开始时都会重新开始,因此尝试格式化非常困难!

我可以通过使用grep并搜索“a”来提取一天开始的索引位置;

newDay <- grep(df$V1, pattern = "a") 

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

data.table::split 看起来可以完成这项工作,但我不确定如何在休息日提供它以按索引位置拆分,或者是否有更合乎逻辑的方式来实现相同的结果而不必打破它直到每一天。

谢谢。

【问题讨论】:

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


    【解决方案1】:

    您可以使用grepl 在“日期时间”中搜索"a",从而得到一个布尔向量。 cumsum 用于创建分组变量的布尔值 - 对于每个 "a" (TRUE),计数器将增加一。

    在每个组中,使用适当的formatorigin(和时区tz?)将第一个元素转换为POSIXct。添加“间隔大小”的倍数(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") 
    

    【讨论】:

    • 不错的解决方案!我一直认为你必须使用formatorigin
    【解决方案2】:

    与:

    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'))
    

    【讨论】:

    • 我收到以下警告;警告消息:在 [.data.table(DT[grep("^a", date), :=(datetime, as.integer(gsub("\\D+", : 强制 'double' RHS 到 'integer' 匹配列的类型;可能有截断精度。要么首先将目标列更改为“double”(通过创建一个新的“double”向量长度 2352(整个表的 nrows)并分配它;即“替换”列),或者强制 RHS为“整数”(例如 1L、NA_[real|integer]_、as.* 等)以使您的意图清晰并加快速度。或者,在创建表格并坚持使用时,预先正确设置列类型,请。
    • @redbaron1981 我也明白,但没什么好担心的。它只是说它将类更改为整数。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-09-03
    • 2021-12-27
    • 2017-04-25
    • 2022-01-08
    相关资源
    最近更新 更多