R,反向累积和

R, Cumulative Sum in Reverse

假设我们有两个 tables:

table 的预算:

Item    Budget
A       900
B       350
C       100
D       0

bDT = structure(list(Item = c("A", "B", "C", "D"), Budget = c(900L, 
350L, 100L, 0L)), .Names = c("Item", "Budget"), row.names = c(NA, 
-4L), class = "data.frame")

以及每个日期按项目列出的 table 预期费用。

 Item       Date Expense
    A 2017-08-24     850
    B 2017-08-18     300
    B 2017-08-11      50
    C 2017-08-18      50
    C 2017-08-11     100
    D 2017-08-01     500

expDF = structure(list(Item = c("A", "B", "B", "C", "C", "D"), Date = structure(c(17402, 
17396, 17389, 17396, 17389, 17379), class = "Date"), Expense = c(850L, 
300L, 50L, 50L, 100L, 500L)), .Names = c("Item", "Date", "Expense"
), row.names = c(NA, -6L), class = "data.frame")

我想总结一下我们每个日期每个项目可以花费的金额,如下所示:

Item    Date        Spend
A       8/24/2017   850
B       8/18/2017   300
B       8/11/2017   50
C       8/18/2017   50
C       8/11/2017   50
D       8/1/2017    0

这个有效:

library(data.table)
setDT(bDF); setDT(expDF)

expDF[bDF, on=.(Item), Spending :=
  pmin(
    Expense, 
    pmax(
      0, 
      Budget - cumsum(shift(Expense, fill=0))
    )
  )
, by=.EACHI]

   Item       Date Expense Spending
1:    A 2017-08-24     850      850
2:    B 2017-08-18     300      300
3:    B 2017-08-11      50       50
4:    C 2017-08-18      50       50
5:    C 2017-08-11     100       50
6:    D 2017-08-01     500        0

工作原理

  • cumsum(shift(Expense, fill = 0)) 是之前的支出**
  • max(0, Budget - prior spending) 是剩余预算
  • min(Expense, 剩余预算) 是当前支出

data.table 语法 x[i, on=, j, by=.EACHI] 是一个连接。在本例中,j 采用 v := expr 的形式,它向 x 添加了一个新列。有关详细信息,请参阅 ?data.table


** 嗯,"prior"在排序中table。我会忽略 OP 奇怪的反转日期。