我有一个数据框,其中包含几个月的安全数据。 数据示例:
TICKER PER DATE TIME OPEN HIGH LOW CLOSE VOL OPENINT
1 RIM4 1 20/03/13 10:55 140000 140000 140000 140000 2 0
2 RIM4 1 20/03/13 12:19 140000 140000 140000 140000 32 0
3 RIM4 1 20/03/13 14:30 140000 140000 140000 140000 1 0
DT dateTime date
1 20/03/13 10:55 2013-03-20 10:55:00 2013-03-20
2 20/03/13 12:19 2013-03-20 12:19:00 2013-03-20
3 20/03/13 14:30 2013-03-20 14:30:00 2013-03-20
我想计算每天的平均值和std.dev。所以我开发了这个脚本:
#progress bar
pbb <- winProgressBar(title="Example progress bar", label="0% done", min=0, max=100, initial=0)
#subsetting
mean <- rep(NA,rim4$date[length(rim4$date)]-rim4$date[1])
std.dev <- rep(NA,rim4$date[length(rim4$date)]-rim4$date[1])
daily <- data.frame(mean,std.dev)
names(daily) <- c("mean","std.dev")
daily$date <- NA
daily$date <- rim4$date[1]
for (i in 2:length(daily$date)) {daily$date[i] <- daily$date[i-1]+86400}
for (i in 1:length(daily$date)) {
subRim4 <- rim4[format(rim4$date, "%Y-%m-%d") == daily$date[i],5]
daily$mean[i] <- mean(subRim4, na.rm = TRUE)
daily$std.dev[i] <- sd(subRim4, na.rm = TRUE)
setWinProgressBar(pbb, i/(length(daily$date))*100)
}
close(pbb)
虽然有效但速度太慢。我的机器需要大约5分钟来管理1年的数据。这有点刺激。 R有办法更快地完成这项工作吗?顺便说一句,如何更新进度条中的%值?在我的情况下它总是显示“0%”? 提前感谢大家。
答案 0 :(得分:1)
data.table
非常快。尝试(未经测试,因为您的数据不能真正重现问题):
library(data.table)
data.table(rim4)[, list(mean(OPEN), sd(OPEN)), by=DATE]
或者,您可以使用dplyr
:
library(dplyr)
rim4 %.% group_by(DATE) %.% summarise(mean(OPEN), sd(OPEN))
希望这个速度足够快,你不需要进度条。另外(出于约瑟夫发布关于xts的好奇心),还有一些基准:
library(microbenchmark)
microbenchmark(
rim4.dt[, list(mean(OPEN), sd(OPEN)), by=DATE],
rim4 %.% group_by(DATE) %.% summarise(mean(OPEN), sd(OPEN)),
apply.daily(x, function(d) c(mean=mean(d), sd=sd(d))),
times=5
)
# Unit: milliseconds
# expr min lq median
# rim4.dt[, list(mean(OPEN), sd(OPEN)), by = DATE] 45.15606 48.94687 53.58172
# rim4 %.% group_by(DATE) %.% summarise(mean(OPEN), sd(OPEN)) 50.42578 50.60166 50.78464
# apply.daily(x, function(d) c(mean = mean(d), sd = sd(d))) 589.46499 592.49094 596.35476
我不确定这是否具有代表性。这是数据:
library(xts)
library(data.table)
library(dplyr)
set.seed(21)
size <- 1e6
val <- rnorm(size)
times <- seq(as.POSIXct("2014-03-28"), by="-1 min", length.out=size)
x <- xts(val, times)
rim4 <- data.frame(DATETIME=times, OPEN=val)
rim4$DATE <- format(rim4$DATETIME, "%Y-%m-%d")
rim4.dt <- data.table(rim4)
答案 1 :(得分:1)
使用实际的时间序列类(如xts),可以轻松完成许多事情:
library(xts)
set.seed(21)
x <- xts(rnorm(1e6), seq(Sys.time(), by="-1 min", length.out=1e6))
y <- apply.daily(x, function(d) c(mean=mean(d), sd=sd(d)))