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

时间:2018-03-16 02:07:26

标签: 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','ProdA','ProdA'),
                 Qty = c(27,-20,15,10,-22),
                 Prc = c(36.47,41.64,40.03,40.95,40.82))

我想计算该产品的运行库存和运行平均值。股票很容易:

ledger[,Stock := cumsum(Qty)]

但是对于平均值,我遇到了一些困难。逻辑如下:如果该行是购买,则平均值应该是先前平均值和新价格的加权平均值。如果是销售,平均价格不会改变。

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

#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

感谢任何帮助!仅供参考,如果您在巴西购买股票,这就是您计算资本收益的方式!

1 个答案:

答案 0 :(得分:1)

数据:

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[, 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