R 使用班次和数据表更新库存值

R 使用班次和数据表更新库存值,r,data.table,R,Data.table,我想使用数据表来计算库存的运行值 例如,以下分类账: ledger <- data.table(Date = c('2017-04-05','2017-06-12','2017-08-12','2017-10-27','2017-11-01'), Op = c('Purchase','Sale','Purchase','Purchase','Sale'), Prod = c('ProdA','ProdA','ProdA',

我想使用数据表来计算库存的运行值

例如,以下分类账:

ledger <- data.table(Date = c('2017-04-05','2017-06-12','2017-08-12','2017-10-27','2017-11-01'),
                 Op = c('Purchase','Sale','Purchase','Purchase','Sale'),
                 Prod = c('ProdA','ProdA','ProdA','ProdA','ProdA'),
                 Qty = c(27,-20,15,10,-22),
                 Prc = c(36.47,41.64,40.03,40.95,40.82))
但是对于平均值,我有一些困难。逻辑如下:如果该行是购买,则平均值应为先前平均值与新价格的加权平均值。如果是销售,平均价格不变

我认为它会起作用的方式:

#This Line doesnt work
ledger[,AvgPrice := ifelse(Op == "Purchase",
                     (Prc * Qty + shift(AvgPrice,1,fill = 0)*shift(Stock,1,fill = 0))/ (Qty + shift(Stock,1,fill = 0)),
                     shift(AvgPrice,1,fill = 0))]
不起作用,因为它是自引用的

作为参考,结果应如下所示:

    Date        Op          Prod    Qty  Prc    Stock   AvgPrice
1   05-04-17    Purchase    ProdA   27   36.47  27      36.47
2   12-06-17    Sale        ProdA   -20  41.64  7       36.47
3   12-08-17    Purchase    ProdA   15   40.03  22      38.90
4   27-10-17    Purchase    ProdA   10   40.95  32      39.54
5   01-11-17    Sale        ProdA   -22  40.82  10      39.54
谢谢你的帮助!仅供参考,如果你在巴西购买股票,这就是你计算资本收益的方式

数据:

library('data.table')
ledger <- data.table(Date = c('2017-04-05','2017-06-12','2017-08-12','2017-10-27','2017-11-01'),
                     Op = c('Purchase','Sale','Purchase','Purchase','Sale'),
                     Prod = c('ProdA','ProdA','ProdA','ProdA','ProdA'),
                     Qty = c(27,-20,15,10,-22),
                     Prc = c(36.47,41.64,40.03,40.95,40.82))
输出:

ledger
#          Date       Op  Prod Qty   Prc Stock AvgPrice
# 1: 2017-04-05 Purchase ProdA  27 36.47    27    36.47
# 2: 2017-06-12     Sale ProdA -20 41.64     7    36.47
# 3: 2017-08-12 Purchase ProdA  15 40.03    22    38.90
# 4: 2017-10-27 Purchase ProdA  10 40.95    32    39.54
# 5: 2017-11-01     Sale ProdA -22 40.82    10    39.54
ledger[, Stock := cumsum(Qty)]  # compute Stock value
ledger[, `:=` ( id = .I, AvgPrice = NA_real_ ) ] # add id and AvgPrice columns
ledger[ 1, AvgPrice := Prc ] # compute AvgPrice for first row

# work with remaining rows and find the AvgPrice
ledger[ ledger[, .I[-1]], AvgPrice := {
  if( Op == "Sale" ){   
    ledger[ .I-1, AvgPrice ]
  } else {
    round( ( ( Qty * Prc ) + ledger[ .I-1, AvgPrice * Stock ] ) /
             ( Qty + ledger[ .I-1, Stock]) ,
           digits = 2 )
  }
}, by = id ]

ledger[, id := NULL ]  # remove id column
ledger
#          Date       Op  Prod Qty   Prc Stock AvgPrice
# 1: 2017-04-05 Purchase ProdA  27 36.47    27    36.47
# 2: 2017-06-12     Sale ProdA -20 41.64     7    36.47
# 3: 2017-08-12 Purchase ProdA  15 40.03    22    38.90
# 4: 2017-10-27 Purchase ProdA  10 40.95    32    39.54
# 5: 2017-11-01     Sale ProdA -22 40.82    10    39.54