合并具有不规则时间戳列的两个数据帧

时间:2015-03-20 03:17:14

标签: r merge dataframe timestamp trading

我有一个与股票相关的数据样本,其价格是以秒为单位的不规则,随机的时间戳记的日期/时间,称为ESH5ESM5

我想生成另一个完整 data.frame,其日期/时间列会按秒增加时间,并使用ESH5,{{1 }}。任何价值都将成为最新价格'除非ESM5ESH5

中的匹配时间存在值,否则将延续到下一个时间间隔

例如,ESM5

ESH5

Date Price Type 22/10/2015 9:00:00 50.10 Bid 22/10/2015 9:00:02 50.12 Ask 22/10/2015 9:00:06 50.10 Trade

ESM5

我希望生成一个完整的data.frame,如

    Date                 Price    Type
    22/10/2015 9:00:01   50.09    Bid
    22/10/2015 9:00:02   50.11    Ask
    22/10/2015 9:00:04   50.09    Trade

目前,我正在使用for循环和if-else语句生成表。我使用常规时间戳增量,最新更新的 Date ESH5.Bid ESH5.Ask ESH5.Trade ESM5.Bid ESM5.Ask ESM5.Trade 22/10/2015 9:00:00 50.10 NA NA NA NA NA 22/10/2015 9:00:01 50.10 NA NA 50.09 NA NA 22/10/2015 9:00:02 50.10 50.12 NA 50.09 50.11 NA 22/10/2015 9:00:03 50.10 50.12 NA 50.09 50.11 NA 22/10/2015 9:00:04 22/10/2015 9:00:05 22/10/2015 9:00:06 NAbid预生成ask空数据框,然后同时运行条件检查以填充表格。

我当前的代码有效,但是循环需要很长时间才能处理(10分钟)。 R中是否有任何内置函数可以用于此搜索并替换和传承类似的功能?

道歉,如果这有点难以理解。谢谢。

2 个答案:

答案 0 :(得分:1)

我认为您想要做的事情需要几个步骤:

首先,使用seq创建日期列,如指示bu @akrun

其次,重建数据结构。这可以通过多种方式完成,但我认为dcast包中的reshape2函数最好:

ESH5c <- dcast(ESH5, Date ~ Type, value.var='Price')
ESM5c <- dcast(ESM5, Date ~ Type, value.var='Price')

最后一步是使用您的日期向量merge这些新数据。

答案 1 :(得分:0)

转换&#39;日期&#39;来自&#39;字符&#39;的数据集中的列上课到&#39; POSIXct&#39;。

ESH5$Date <- as.POSIXct(ESH5$Date, format='%d/%m/%Y %H:%M:%S')
ESM5$Date <- as.POSIXct(ESM5$Date, format='%d/%m/%Y %H:%M:%S')

获得“分钟”&#39;和&#39; max&#39;通过连接&#39;日期&#39;这些数据集的列。

MinD <- min(c(ESH5$Date, ESM5$Date))
MaxD <- max(c(ESH5$Date, ESM5$Date))

根据&#39; MinD&#39;和&#39; MaxD&#39;创建一系列日期时间。值作为新数据集

d1 <- data.frame(Date=seq(MinD, MaxD, by='sec'))

merge将所有数据集放入&#39;列表中。并使用Reduce

d2 <- Reduce(function(...) merge(..., by='Date', all=TRUE),
           list(d1, ESH5, ESM5))

重塑&#39; d2&#39;广泛的数据集&#39;长期&#39;

dLong <- reshape(d2, idvar='Date', varying=2:5, sep=".", direction='long')
dLong$time <- factor(dLong$time, labels=c('ESH5', 'ESM5'))
row.names(dLong) <- NULL

更改&#39; long&#39;格式为&#39;宽&#39;使用dcast

library(reshape2) 
res <- dcast(dLong, Date~time+Type, value.var='Price')

删除额外的NA列

res1 <- res[!grepl('NA', names(res))]

使用na.locf中的zoo使用之前的非NA值填充NA值

library(zoo)
res1[-1] <- lapply(res1[-1], na.locf, na.rm=FALSE)
res1
#                 Date ESH5_Ask ESH5_Bid ESH5_Trade ESM5_Ask ESM5_Bid ESM5_Trade
#1 2015-10-22 09:00:00       NA     50.1         NA       NA       NA         NA
#2 2015-10-22 09:00:01       NA     50.1         NA       NA    50.09         NA
#3 2015-10-22 09:00:02    50.12     50.1         NA    50.11    50.09         NA
#4 2015-10-22 09:00:03    50.12     50.1         NA    50.11    50.09         NA
#5 2015-10-22 09:00:04    50.12     50.1         NA    50.11    50.09      50.09
#6 2015-10-22 09:00:05    50.12     50.1         NA    50.11    50.09      50.09
#7 2015-10-22 09:00:06    50.12     50.1       50.1    50.11    50.09      50.09

或者使用dplyr/tidyr,我们可以使用spread更改每个数据集的格式full_join,以及&#39; d1&#39;,更改&# 39; NA&#39;每列中的值与非NA&#39;使用na.locfmutate_each的上一个值。使用paste更改列名称(如果需要)。

 library(dplyr)
 library(tidyr)
 library(zoo)

 res2 <-  full_join(spread(ESH5, Type, Price), 
                        spread(ESM5, Type, Price), by='Date') %>%
                    full_join(d1, ., by='Date') %>%
                    mutate_each(funs(na.locf(., na.rm=FALSE)), -Date) 

 names(res2)[-1] <- c(paste('ESH5', sort(ESH5$Type),sep="_"), 
                      paste('ESM5', sort(ESM5$Type), sep="_"))

  res2
  #               Date ESH5_Ask ESH5_Bid ESH5_Trade ESM5_Ask ESM5_Bid ESM5_Trade
  #1 2015-10-22 09:00:00       NA     50.1         NA       NA       NA         NA
  #2 2015-10-22 09:00:01       NA     50.1         NA       NA    50.09         NA
  #3 2015-10-22 09:00:02    50.12     50.1         NA    50.11    50.09         NA
  #4 2015-10-22 09:00:03    50.12     50.1         NA    50.11    50.09         NA
  #5 2015-10-22 09:00:04    50.12     50.1         NA    50.11    50.09      50.09
  #6 2015-10-22 09:00:05    50.12     50.1         NA    50.11    50.09      50.09
  #7 2015-10-22 09:00:06    50.12     50.1       50.1    50.11    50.09      50.09