使用三个其他给定变量迭代或按行滚动计算两个联立变量
Rolling computation of two simultaneous variables iteratively or rowwise, using three other given variables
名为 crass
的数据集看起来像 -
> dput(crass)
structure(list(WT_TRADE_PRICE = c(3801, 3801, 3801, 3797, 3797,
3796.2125, 3800, 3797, 3795.09523809524, 3794, 3793, 3793, 3793.8,
3794.72, 3793.02777777778, 3789, 3790, 3788, 3788, 3788), min = c(3801,
3801, 3801, 3797, 3797, 3795, 3800, 3797, 3794, 3794, 3793, 3793,
3793, 3794, 3790, 3789, 3790, 3788, 3788, 3788), max = c(3801,
3801, 3801, 3797, 3797, 3800, 3800, 3797, 3797, 3794, 3793, 3793,
3794, 3797, 3794, 3789, 3790, 3788, 3788, 3788), Bid = c(3801,
NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA,
NA, NA, NA), Ask = c(3802, NA, NA, NA, NA, NA, NA, NA, NA, NA,
NA, NA, NA, NA, NA, NA, NA, NA, NA, 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
的值 >=
或 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
min
max
Bid
Ask
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::accumulate
通常基于一个输入在一个输出上工作,而 purrr::accumulate2()
在 2 个输入上再次工作一个输出。因此,我对 accumulate
的策略如下:-
- Re-arrange 三个输入列每个输入 row-wise tibbles,因此三列输入中的每一列现在都是一列。为此,我生成了一个虚拟列
id
以便每一行都转换为一个小标题。
- 我为此使用了
tidyr::nest_by()
- 对于输出,我再次通过 accumulate 生成了一个 tibble 而不是一个向量。
- 最后,我使用
tidyr::unnnest_wider()
将两个 tibbles 转换回其原始形状
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, (.x$Ask + .x$Bid)/2),
.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
您还可以在 base 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"]], (x[["Ask"]] + x[["Bid"]])/2),
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
名为 crass
的数据集看起来像 -
> dput(crass)
structure(list(WT_TRADE_PRICE = c(3801, 3801, 3801, 3797, 3797,
3796.2125, 3800, 3797, 3795.09523809524, 3794, 3793, 3793, 3793.8,
3794.72, 3793.02777777778, 3789, 3790, 3788, 3788, 3788), min = c(3801,
3801, 3801, 3797, 3797, 3795, 3800, 3797, 3794, 3794, 3793, 3793,
3793, 3794, 3790, 3789, 3790, 3788, 3788, 3788), max = c(3801,
3801, 3801, 3797, 3797, 3800, 3800, 3797, 3797, 3794, 3793, 3793,
3794, 3797, 3794, 3789, 3790, 3788, 3788, 3788), Bid = c(3801,
NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA,
NA, NA, NA), Ask = c(3802, NA, NA, NA, NA, NA, NA, NA, NA, NA,
NA, NA, NA, NA, NA, NA, NA, NA, NA, 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
的值>=
或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 | min | max | Bid | Ask |
---|---|---|---|---|---|
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::accumulate
通常基于一个输入在一个输出上工作,而 purrr::accumulate2()
在 2 个输入上再次工作一个输出。因此,我对 accumulate
的策略如下:-
- Re-arrange 三个输入列每个输入 row-wise tibbles,因此三列输入中的每一列现在都是一列。为此,我生成了一个虚拟列
id
以便每一行都转换为一个小标题。 - 我为此使用了
tidyr::nest_by()
- 对于输出,我再次通过 accumulate 生成了一个 tibble 而不是一个向量。
- 最后,我使用
tidyr::unnnest_wider()
将两个 tibbles 转换回其原始形状
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, (.x$Ask + .x$Bid)/2),
.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
您还可以在 base 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"]], (x[["Ask"]] + x[["Bid"]])/2),
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