我有一个与股票相关的数据样本,其价格是以秒为单位的不规则,随机的时间戳记的日期/时间,称为ESH5
和ESM5
我想生成另一个完整 data.frame,其日期/时间列会按秒增加时间,并使用ESH5
,{{1 }}。任何价值都将成为最新价格'除非ESM5
或ESH5
例如,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
,NA
,bid
预生成ask
空数据框,然后同时运行条件检查以填充表格。
我当前的代码有效,但是循环需要很长时间才能处理(10分钟)。 R中是否有任何内置函数可以用于此搜索并替换和传承类似的功能?
道歉,如果这有点难以理解。谢谢。
答案 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.locf
和mutate_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