根据先前的值和 data.table 中的另一个变量填充一个变量
Populating a variable based on previous values and another variable in a data.table
我有订单和交易数据,需要计算订单发生交易后的剩余交易量。在下面的数据中,我们有相对于订单的交易量,交易发生在状态==2 时。
Order Status Volume Traded RemainingVolume
1: 412 1 100 NA 100
2: 412 2 NA 46 NA
3: 412 2 NA 15 NA
4: 412 2 NA 39 NA
5: 538 1 10 NA 10
6: 538 2 NA 7 NA
7: 538 2 NA 3 NA
8: 592 1 389 NA 389
9: 592 2 NA 95 NA
10: 648 1 100 NA 100
11: 648 2 NA 100 NA
12: 885 1 50 NA 50
13: 885 2 NA 47 NA
14: 885 2 NA 3 NA
15: 950 1 39 NA 39
16: 950 2 NA 39 NA
我只需要计算每个订单的剩余数量。这是通过从交易量中减去交易量(交易量)来计算的。由于开头的 RemainingVolume (status==1) 无论如何设置为 Volume,这就是 (RemainingVolume-Traded),即
全部。换句话说,我需要以下输出:
Order Status Volume Traded RemainingVolume
1: 412 1 100 NA 100
2: 412 2 NA 46 54
3: 412 2 NA 15 39
4: 412 2 NA 39 0
5: 538 1 10 NA 10
6: 538 2 NA 7 3
7: 538 2 NA 3 0
8: 592 1 389 NA 389
9: 592 2 NA 95 294
10: 648 1 100 NA 100
11: 648 2 NA 100 0
12: 885 1 50 NA 50
13: 885 2 NA 47 3
14: 885 2 NA 3 0
15: 950 1 39 NA 39
16: 950 2 NA 39 0
注意订单 412、538、592、648、885 和 950 的剩余交易量是如何成交的。假设数据在 table mz 中,rem 是 RemainingVolume,trdq 是已交易,我试过以下:
for (i in 2:nrow(mz)){
if (is.na(mz[i]$rem))mz[i]$rem = mz[i-1]$rem - mz[i]$trdq
}
有效,但速度真的非常慢。这里的数据有数百万行,因此只有 data.table 解决方案是可行的。所以我尝试了:
mz[,rem:= ifelse(is.na(rem), shift(rem, 1)-trdq, rem), by = ord]
这里也没有答案。我得到了第一笔交易的 RemainingVolume,仅此而已。下面的交易仍然是 NA。我在这里错过了什么?我是 data.table 的新手,所以可能很简单。
考虑到数据的大小,性能在这里确实很关键。非常感谢任何帮助。
对于每个 Order
从 first
RemainingVolume
中减去 Traded
的累积总和。
由于您的数据量很大,您可以在 data.table
中执行此操作:
library(data.table)
setDT(df)[,RemainingVolume := first(RemainingVolume) -
c(0, cumsum(Traded[-1])), Order]
df
# Order Status Volume Traded RemainingVolume
# 1: 412 1 100 NA 100
# 2: 412 2 NA 46 54
# 3: 412 2 NA 15 39
# 4: 412 2 NA 39 0
# 5: 538 1 10 NA 10
# 6: 538 2 NA 7 3
# 7: 538 2 NA 3 0
# 8: 592 1 389 NA 389
# 9: 592 2 NA 95 294
#10: 648 1 100 NA 100
#11: 648 2 NA 100 0
#12: 885 1 50 NA 50
#13: 885 2 NA 47 3
#14: 885 2 NA 3 0
#15: 950 1 39 NA 39
#16: 950 2 NA 39 0
baseR 的实现方式
dt$RemainingVolume <- ave(replace(dt$RemainingVolume, dt$Status ==2, -1*dt$Traded[dt$Status ==2]), dt$Order, FUN = function(x) cumsum(x))
dt
Order Status Volume Traded RemainingVolume
1: 412 1 100 NA 100
2: 412 2 NA 46 54
3: 412 2 NA 15 39
4: 412 2 NA 39 0
5: 538 1 10 NA 10
6: 538 2 NA 7 3
7: 538 2 NA 3 0
8: 592 1 389 NA 389
9: 592 2 NA 95 294
10: 648 1 100 NA 100
11: 648 2 NA 100 0
12: 885 1 50 NA 50
13: 885 2 NA 47 3
14: 885 2 NA 3 0
15: 950 1 39 NA 39
16: 950 2 NA 39 0
使用的示例数据
dt <- structure(list(Order = c(412L, 412L, 412L, 412L, 538L, 538L,
538L, 592L, 592L, 648L, 648L, 885L, 885L, 885L, 950L, 950L),
Status = c(1L, 2L, 2L, 2L, 1L, 2L, 2L, 1L, 2L, 1L, 2L, 1L,
2L, 2L, 1L, 2L), Volume = c(100L, NA, NA, NA, 10L, NA, NA,
389L, NA, 100L, NA, 50L, NA, NA, 39L, NA), Traded = c(NA,
46L, 15L, 39L, NA, 7L, 3L, NA, 95L, NA, 100L, NA, 47L, 3L,
NA, 39L), RemainingVolume = c(100, 54, 39, 0, 10, 3, 0, 389,
294, 100, 0, 50, 3, 0, 39, 0)), row.names = c(NA, -16L), class = "data.frame")
我有订单和交易数据,需要计算订单发生交易后的剩余交易量。在下面的数据中,我们有相对于订单的交易量,交易发生在状态==2 时。
Order Status Volume Traded RemainingVolume
1: 412 1 100 NA 100
2: 412 2 NA 46 NA
3: 412 2 NA 15 NA
4: 412 2 NA 39 NA
5: 538 1 10 NA 10
6: 538 2 NA 7 NA
7: 538 2 NA 3 NA
8: 592 1 389 NA 389
9: 592 2 NA 95 NA
10: 648 1 100 NA 100
11: 648 2 NA 100 NA
12: 885 1 50 NA 50
13: 885 2 NA 47 NA
14: 885 2 NA 3 NA
15: 950 1 39 NA 39
16: 950 2 NA 39 NA
我只需要计算每个订单的剩余数量。这是通过从交易量中减去交易量(交易量)来计算的。由于开头的 RemainingVolume (status==1) 无论如何设置为 Volume,这就是 (RemainingVolume-Traded),即 全部。换句话说,我需要以下输出:
Order Status Volume Traded RemainingVolume
1: 412 1 100 NA 100
2: 412 2 NA 46 54
3: 412 2 NA 15 39
4: 412 2 NA 39 0
5: 538 1 10 NA 10
6: 538 2 NA 7 3
7: 538 2 NA 3 0
8: 592 1 389 NA 389
9: 592 2 NA 95 294
10: 648 1 100 NA 100
11: 648 2 NA 100 0
12: 885 1 50 NA 50
13: 885 2 NA 47 3
14: 885 2 NA 3 0
15: 950 1 39 NA 39
16: 950 2 NA 39 0
注意订单 412、538、592、648、885 和 950 的剩余交易量是如何成交的。假设数据在 table mz 中,rem 是 RemainingVolume,trdq 是已交易,我试过以下:
for (i in 2:nrow(mz)){
if (is.na(mz[i]$rem))mz[i]$rem = mz[i-1]$rem - mz[i]$trdq
}
有效,但速度真的非常慢。这里的数据有数百万行,因此只有 data.table 解决方案是可行的。所以我尝试了:
mz[,rem:= ifelse(is.na(rem), shift(rem, 1)-trdq, rem), by = ord]
这里也没有答案。我得到了第一笔交易的 RemainingVolume,仅此而已。下面的交易仍然是 NA。我在这里错过了什么?我是 data.table 的新手,所以可能很简单。
考虑到数据的大小,性能在这里确实很关键。非常感谢任何帮助。
对于每个 Order
从 first
RemainingVolume
中减去 Traded
的累积总和。
由于您的数据量很大,您可以在 data.table
中执行此操作:
library(data.table)
setDT(df)[,RemainingVolume := first(RemainingVolume) -
c(0, cumsum(Traded[-1])), Order]
df
# Order Status Volume Traded RemainingVolume
# 1: 412 1 100 NA 100
# 2: 412 2 NA 46 54
# 3: 412 2 NA 15 39
# 4: 412 2 NA 39 0
# 5: 538 1 10 NA 10
# 6: 538 2 NA 7 3
# 7: 538 2 NA 3 0
# 8: 592 1 389 NA 389
# 9: 592 2 NA 95 294
#10: 648 1 100 NA 100
#11: 648 2 NA 100 0
#12: 885 1 50 NA 50
#13: 885 2 NA 47 3
#14: 885 2 NA 3 0
#15: 950 1 39 NA 39
#16: 950 2 NA 39 0
baseR 的实现方式
dt$RemainingVolume <- ave(replace(dt$RemainingVolume, dt$Status ==2, -1*dt$Traded[dt$Status ==2]), dt$Order, FUN = function(x) cumsum(x))
dt
Order Status Volume Traded RemainingVolume
1: 412 1 100 NA 100
2: 412 2 NA 46 54
3: 412 2 NA 15 39
4: 412 2 NA 39 0
5: 538 1 10 NA 10
6: 538 2 NA 7 3
7: 538 2 NA 3 0
8: 592 1 389 NA 389
9: 592 2 NA 95 294
10: 648 1 100 NA 100
11: 648 2 NA 100 0
12: 885 1 50 NA 50
13: 885 2 NA 47 3
14: 885 2 NA 3 0
15: 950 1 39 NA 39
16: 950 2 NA 39 0
使用的示例数据
dt <- structure(list(Order = c(412L, 412L, 412L, 412L, 538L, 538L,
538L, 592L, 592L, 648L, 648L, 885L, 885L, 885L, 950L, 950L),
Status = c(1L, 2L, 2L, 2L, 1L, 2L, 2L, 1L, 2L, 1L, 2L, 1L,
2L, 2L, 1L, 2L), Volume = c(100L, NA, NA, NA, 10L, NA, NA,
389L, NA, 100L, NA, 50L, NA, NA, 39L, NA), Traded = c(NA,
46L, 15L, 39L, NA, 7L, 3L, NA, 95L, NA, 100L, NA, 47L, 3L,
NA, 39L), RemainingVolume = c(100, 54, 39, 0, 10, 3, 0, 389,
294, 100, 0, 50, 3, 0, 39, 0)), row.names = c(NA, -16L), class = "data.frame")