R 基于先前的值和data.table中的另一个变量填充变量

R 基于先前的值和data.table中的另一个变量填充变量,r,performance,data.table,bigdata,calculated-columns,R,Performance,Data.table,Bigdata,Calculated Columns,我有订单和交易数据,需要计算订单上发生交易后的剩余交易量。根据下面的数据,我们有针对订单的交易量,交易发生在status==2时 Order Status Volume Traded RemainingVolume 1: 412 1 100 NA 100 2: 412 2 NA 46 NA 3: 412 2 NA 15

我有订单和交易数据,需要计算订单上发生交易后的剩余交易量。根据下面的数据,我们有针对订单的交易量,交易发生在status==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(状态==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
请注意订单41253859264885和950的剩余数量是如何填充的。假设数据在表mz中,rem是剩余量,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]
这里也没有答案。我得到了第一笔交易的剩余量,但仅此而已。下面的交易仍然是NA。我错过了什么?我不熟悉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
更卑鄙的做法

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$RemainingVolume非常感谢,这很有帮助。不过,只有一个问题。当Status==1的条目多次出现时,解决方案似乎不起作用。我应该早一点澄清这一点。@TirthankarPatnaik在这种情况下,输出是什么?你能用这样一个例子来更新你的文章并展示它的输出吗?你仔细地阅读了你的代码,并且能够根据我们的要求来塑造它。谢谢。以一种新的方式理解了“:=”运算符的威力。非常感谢。我不明白的是为什么使用trade[1]。
trade[1]
有一个值,我们要从中减去
trade
值。因此,对于412
Order
它是100,对于538它是10。
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")