问题描述
名为 crass
的数据集看起来像 -
> dput(crass)
structure(list(WT_TradE_PRICE = c(3801,3801,3797,3796.2125,3800,3795.09523809524,3794,3793,3793.8,3794.72,3793.02777777778,3789,3790,3788,3788),min = c(3801,3795,max = c(3801,Bid = c(3801,NA,NA),Ask = c(3802,NA)),row.names = c(NA,-20L
),class = c("tbl_df","tbl","data.frame"))
# A tibble: 20 x 5
WT_TradE_PRICE min max Bid Ask
<dbl> <dbl> <dbl> <dbl> <dbl>
1 3801 3801 3801 3801 3802
2 3801 3801 3801 NA NA
3 3801 3801 3801 NA NA
4 3797 3797 3797 NA NA
5 3797 3797 3797 NA NA
6 3796. 3795 3800 NA NA
7 3800 3800 3800 NA NA
8 3797 3797 3797 NA NA
9 3795. 3794 3797 NA NA
10 3794 3794 3794 NA NA
11 3793 3793 3793 NA NA
12 3793 3793 3793 NA NA
13 3794. 3793 3794 NA NA
14 3795. 3794 3797 NA NA
15 3793. 3790 3794 NA NA
16 3789 3789 3789 NA NA
17 3790 3790 3790 NA NA
18 3788 3788 3788 NA NA
19 3788 3788 3788 NA NA
20 3788 3788 3788 NA NA
可以看出,两个变量 ask
和 bid
只有初始值,需要使用以下逻辑迭代填充。
- 如果
WT_TRDAE_PRICE
比>=
的先前值Ask
OR 将检查WT_TradE_PRICE
是否比先前的平均值>
bid
和ask
- 那么当前ask
将被设置为等于当前行max
变量,bid
将被设置为等于之前的bid
值. - 否则,当前
ask
将设置为之前的ask
值,而bid
将设置为max
。
伪代码-
if(WT_TradE_PRICE >= L(Ask) | WT_TradE_PRICE > (L(Bid)+L(Ask))/2)
{
Bid = L(Bid),Ask = max
}
else
{
Bid = min,Ask = L(Ask)
}
最终输出 -
SNo. | WT_TradE_PRICE | 分钟 | 最大 | 出价 | 询问 |
---|---|---|---|---|---|
1 | 3801 | 3801 | 3801 | 3801 | 3802 |
2 | 3801 | 3801 | 3801 | 3801 | 3802 |
3 | 3801 | 3801 | 3801 | 3801 | 3802 |
4 | 3797 | 3797 | 3797 | 3797 | 3802 |
5 | 3797 | 3797 | 3797 | 3797 | 3802 |
6 | 3796. | 3795 | 3800 | 3795 | 3802 |
7 | 3800 | 3800 | 3800 | 3795 | 3800 |
8 | 3797 | 3797 | 3797 | 3797 | 3800 |
9 | 3795. | 3794 | 3797 | 3794 | 3800 |
10 | 3794 | 3794 | 3794 | 3794 | 3800 |
11 | 3793 | 3793 | 3793 | 3793 | 3800 |
12 | 3793 | 3793 | 3793 | 3793 | 3800 |
13 | 3794. | 3793 | 3794 | 3793 | 3800 |
14 | 3795. | 3794 | 3797 | 3793 | 3797 |
15 | 3793. | 3790 | 3794 | 3790 | 3797 |
16 | 3789 | 3789 | 3789 | 3789 | 3797 |
17 | 3790 | 3790 | 3790 | 3790 | 3797 |
18 | 3788 | 3788 | 3788 | 3788 | 3797 |
19 | 3788 | 3788 | 3788 | 3788 | 3797 |
20 | 3788 | 3788 | 3788 | 3788 | 3797 |
解决方法
进一步编辑
根据要求,我尝试使用 purrr
风格的语法,现在应该可以达到目的并且速度也应该很快
crass[1:3] %>%
nest_by(id = row_number()) %>%
ungroup() %>%
mutate(new = accumulate(data,.init = list(Bid = 3801,Ask = 3802),~ tibble(Bid = ifelse(.y$WT_TRADE_PRICE >= min(.x$Ask,(.x$Ask + .x$Bid)/2),.x$Bid,.y$min),Ask = ifelse(.y$WT_TRADE_PRICE >= min(.x$Ask,.y$max,.x$Ask))
)[-1]) %>%
unnest_wider(data) %>%
unnest_wider(new)
# A tibble: 20 x 6
id WT_TRADE_PRICE min max Bid Ask
<int> <dbl> <dbl> <dbl> <dbl> <dbl>
1 1 3801 3801 3801 3801 3802
2 2 3801 3801 3801 3801 3802
3 3 3801 3801 3801 3801 3802
4 4 3797 3797 3797 3797 3802
5 5 3797 3797 3797 3797 3802
6 6 3796. 3795 3800 3795 3802
7 7 3800 3800 3800 3795 3800
8 8 3797 3797 3797 3797 3800
9 9 3795. 3794 3797 3794 3800
10 10 3794 3794 3794 3794 3800
11 11 3793 3793 3793 3793 3800
12 12 3793 3793 3793 3793 3800
13 13 3794. 3793 3794 3793 3800
14 14 3795. 3794 3797 3794 3800
15 15 3793. 3790 3794 3790 3800
16 16 3789 3789 3789 3789 3800
17 17 3790 3790 3790 3790 3800
18 18 3788 3788 3788 3788 3800
19 19 3788 3788 3788 3788 3800
20 20 3788 3788 3788 3788 3800
较早修订的 for 循环
语法
for(i in 2:nrow(crass)){
if(crass[i,1] >= min(crass[i-1,5],(crass[i-1,4] + crass[i-1,5])/2)){
crass[i,5] <- crass[i,3]
crass[i,4] <- crass[i-1,4]
} else {
crass[i,4] <- crass[i,2]
crass[i,5] <- crass[i-1,5]
}
}
crass
# A tibble: 20 x 5
WT_TRADE_PRICE min max Bid Ask
<dbl> <dbl> <dbl> <dbl> <dbl>
1 3801 3801 3801 3801 3802
2 3801 3801 3801 3801 3802
3 3801 3801 3801 3801 3802
4 3797 3797 3797 3797 3802
5 3797 3797 3797 3797 3802
6 3796. 3795 3800 3795 3802
7 3800 3800 3800 3795 3800
8 3797 3797 3797 3797 3800
9 3795. 3794 3797 3794 3800
10 3794 3794 3794 3794 3800
11 3793 3793 3793 3793 3800
12 3793 3793 3793 3793 3800
13 3794. 3793 3794 3793 3800
14 3795. 3794 3797 3794 3800
15 3793. 3790 3794 3790 3800
16 3789 3789 3789 3789 3800
17 3790 3790 3790 3790 3800
18 3788 3788 3788 3788 3800
19 3788 3788 3788 3788 3800
20 3788 3788 3788 3788 3800
crass
for 循环运行前
# A tibble: 20 x 5
WT_TRADE_PRICE min max Bid Ask
<dbl> <dbl> <dbl> <dbl> <dbl>
1 3801 3801 3801 3801 3802
2 3801 3801 3801 NA NA
3 3801 3801 3801 NA NA
4 3797 3797 3797 NA NA
5 3797 3797 3797 NA NA
6 3796. 3795 3800 NA NA
7 3800 3800 3800 NA NA
8 3797 3797 3797 NA NA
9 3795. 3794 3797 NA NA
10 3794 3794 3794 NA NA
11 3793 3793 3793 NA NA
12 3793 3793 3793 NA NA
13 3794. 3793 3794 NA NA
14 3795. 3794 3797 NA NA
15 3793. 3790 3794 NA NA
16 3789 3789 3789 NA NA
17 3790 3790 3790 NA NA
18 3788 3788 3788 NA NA
19 3788 3788 3788 NA NA
20 3788 3788 3788 NA NA
,
您也可以在基础 R 中使用以下解决方案。
对于这个解决方案,我使用行号作为 Reduce
中使用的主要向量。我们可以在有多个输出变量的情况下使用这种技术。应该注意的是,为了区分 Bid
和 Ask
的先前值,我使用了双括号来对所需值进行子集化。
cbind(crass[1:3],do.call(rbind,Reduce(function(x,y) {
data.frame(Bid = ifelse(crass$WT_TRADE_PRICE[y] >= min(x[["Ask"]],(x[["Ask"]] + x[["Bid"]])/2),x[["Bid"]],crass$min[y]),Ask = ifelse(crass$WT_TRADE_PRICE[y] >= min(x[["Ask"]],crass$max[y],x[["Ask"]]))
},init = data.frame(Bid = crass$Bid[1],Ask = crass$Ask[1]),seq_len(nrow(crass))[-1],accumulate = TRUE)))
结果
WT_TRADE_PRICE min max Bid Ask
1 3801.000 3801 3801 3801 3802
2 3801.000 3801 3801 3801 3802
3 3801.000 3801 3801 3801 3802
4 3797.000 3797 3797 3797 3802
5 3797.000 3797 3797 3797 3802
6 3796.213 3795 3800 3795 3802
7 3800.000 3800 3800 3795 3800
8 3797.000 3797 3797 3797 3800
9 3795.095 3794 3797 3794 3800
10 3794.000 3794 3794 3794 3800
11 3793.000 3793 3793 3793 3800
12 3793.000 3793 3793 3793 3800
13 3793.800 3793 3794 3793 3800
14 3794.720 3794 3797 3794 3800
15 3793.028 3790 3794 3790 3800
16 3789.000 3789 3789 3789 3800
17 3790.000 3790 3790 3790 3800
18 3788.000 3788 3788 3788 3800
19 3788.000 3788 3788 3788 3800
20 3788.000 3788 3788 3788 3800