我有一个包含两列的数据框 - 时间和价格。它包含一系列关于某个项目在不同时间的价格的观察。这是一个样本。
> df
time price
1 2014-12-12 14:57:15 45.81
2 2014-12-12 14:57:15 45.90
3 2014-12-12 15:00:08 45.76
4 2014-12-12 15:00:37 45.72
5 2014-12-12 15:00:49 45.73
6 2014-12-12 15:00:49 45.72
7 2014-12-12 15:00:49 45.76
8 2014-12-12 15:00:49 45.76
9 2014-12-12 15:00:50 45.78
10 2014-12-12 15:00:57 45.76
11 2014-12-12 15:00:57 45.76
12 2014-12-12 15:01:01 45.74
13 2014-12-12 15:01:01 45.74
14 2014-12-12 15:01:08 45.74
15 2014-12-12 15:01:08 45.74
16 2014-12-12 15:01:22 48.79
17 2014-12-12 15:01:23 45.72
18 2014-12-12 15:01:26 45.86
19 2014-12-12 15:01:50 45.72
20 2014-12-12 15:02:00 45.80
在每个观察点,我想计算下一个24小时窗口中任一方向的最大价格波动。
> max(df$price - df$price[1])
[1] 2.98
> min(df$price - df$price[1])
[1] -0.09
因此,对于上述示例中的观察1,最大波动为2.98和-0.09。我可以写一个像
这样的函数 fluc <- function(i) {
c(max(df$price - df$price[i]), min(df$price - df$price[i]))
}
并使用lapply,但这将计算整个数据框架的差异。我想将计算限制在接下来的24小时内,因此对于不同的观察点,计算的差异数量会有所不同。
我可以编写一个n ^ 2函数来执行此操作,但是有一种R友好的方法来实现这一点吗?理想情况下,我也想要发生最大波动的时间。
谢谢。
添加输出输出:
structure(list(time = structure(c(1418425035.677, 1418425035.677,
1418425208.407, 1418425237.587, 1418425249.22, 1418425249.22,
1418425249.38, 1418425249.38, 1418425250.64, 1418425257.97, 1418425257.97,
1418425261.397, 1418425261.397, 1418425268.333, 1418425268.333,
1418425282.207, 1418425283.403, 1418425286.083, 1418425310.893,
1418425320.42), class = c("POSIXct", "POSIXt"), tzone = ""),
price = c(45.81, 45.9, 45.76, 45.72, 45.73, 45.72, 45.76,
45.76, 45.78, 45.76, 45.76, 45.74, 45.74, 45.74, 45.74, 48.79,
45.72, 45.86, 45.72, 45.8)), .Names = c("time", "price"), row.names = c(NA,
20L), class = "data.frame")
答案 0 :(得分:1)
我想它会起作用。我不认为这是最好的方法,但我知道你想要使用数据。
myFunc <- function(df, startDate, endDate) {
df <- df[df$time > startDate & df$time <= endDate, ]
gain <- as.numeric(NA)
for(i in 2:nrow(df)) {
gain <- c(gain, df$price[i] - df$price[i-1])
}
max <- df[which(gain == max(gain, na.rm=TRUE)), ]
min <- df[which(gain == min(gain, na.rm=TRUE)), ]
list(max=max, min=min)
}
x <- myFunc(df, time[5], time[15])
答案 1 :(得分:0)
这似乎有效。尝试使用日期作为底部窗口截止,我被绊倒了,但是重复项将0添加为最小值,否则将没有。
as.POSIXct可能没有必要,具体取决于您的日期格式。我也用了60秒才使它变得有趣。
# create upper cutoff for each row
df$cutoff <- as.POSIXct(df$time) + 60 # 24 is 60*60*24
# a for loop works well too
result <- mapply(function(end,rowid,x){
# create window, and return min/max
window <- x[as.numeric(row.names(x)) >= rowid & x$time <= end,'price']
c(min(window - window[1]),max(window - window[1]))
},end = df$cutoff,rowid = 1:nrow(df),MoreArgs = list(x = df[ ,c('time','price')]))
# do whatever with the result
cbind(df,t(result))
更新,包括最大波动的时间:
df$cutoff <- as.POSIXct(df$time) + 60 # 24 is 60*60*24
result <- list()
for(i in 1:(nrow(df)-1)){
# create window, add diffs, send matching window result
window <- df[as.numeric(row.names(df)) >= i + 1 & df$time <= df$cutoff[i],c('time','price')]
window$diffs <- window$price - window$price[1]
result[[i]] <- (c(i,window[window$diffs == max(window$diffs), ],window[window$diffs == min(window$diffs), ]))
}
# prep data for merging
resultdf <- as.data.frame(do.call('rbind',result))
names(resultdf) <- c('i','maxtime','maxprice','maxdiff','mintime','minprice','mindiff')
df$rowid <- 1:nrow(df)
# merge
merge(df,resultdf,by.x = 'row.names',by.y = 'i',all.x = T,sort = F)
我的猜测是* pply函数不会使任何更优雅,因为每次迭代都需要起始行,主data.frame和max行。预处理和矢量化可能会有所帮助。