R 基于先前的值和data.table中的另一个变量填充变量
我有订单和交易数据,需要计算订单上发生交易后的剩余交易量。根据下面的数据,我们有针对订单的交易量,交易发生在status==2时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
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
值。因此,对于412Order
它是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")