首页 > 解决方案 > 根据先前的值和 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 的剩余量是如何填充的。假设数据在表 mz 中,rem 是 RemainingVolume,trdq 是 Traded,我尝试了以下操作:

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 的新手,所以可能很简单。

考虑到数据的大小,性能在这里确实是关键。任何帮助深表感谢。

标签: rperformancedata.tablebigdatacalculated-columns

解决方案


对于每个从Order中减去的累积和。Tradedfirst RemainingVolume

由于您的数据很大,您可以在以下位置执行此操作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

推荐阅读