【问题标题】:R, Cumulative Sum in ReverseR,反向累积和
【发布时间】:2017-07-31 18:45:55
【问题描述】:

假设我们有两个表:

预算表:

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")

以及每个日期按项目的预期费用表。

 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

【问题讨论】:

  • 仅供参考,如果您使用 Date 类列并提供易于重现示例的代码,对每个人来说都更好/更容易。请参阅stackoverflow.com/questions/5963269/… 以获得指导。
  • 我看不出这与累积求和有什么关系。但我不明白结果是如何产生的逻辑。为什么D 0?
  • @Gregor 这就像Budget - cumsum(data.table::shift(Expense, type = "lead")),我猜,显示当前费用之前的预算金额。嗯,不,这也不太合适,因为两个 C 都是 50,好吧,我迷路了……也许那个,加上 pmaxpmin 某处。
  • @Gregor Spend 是每个日期每个项目可用的总预算(按降序排列)。因此,对于 D,“支出”为 0,因为我们没有“预算”。
  • 那么C 8/11/2017 50不应该等于0吗?

标签: r cumsum


【解决方案1】:

这行得通:

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 - 先前支出) 是剩余预算
  • 分钟(费用,剩余预算)是当前支出

data.table 语法x[i, on=, j, by=.EACHI] 是一个连接。在这种情况下,j 采用v := expr 的形式,它向x 添加了一个新列。详情请见?data.table


** 好吧,在表格的排序中“优先”。我将忽略 OP 奇怪的颠倒日期。

【讨论】:

  • 非常好!在安装 data.table 时还从 DataCamp 找到了这些教程:link
  • @J.D.Marlin 是的,data.table 作者的这门课程对于快速掌握软件包非常有帮助。
猜你喜欢
  • 2021-01-15
  • 2018-02-28
  • 2016-10-18
  • 2013-05-08
  • 2014-09-29
  • 1970-01-01
  • 2016-02-19
  • 1970-01-01
  • 2021-12-01
相关资源
最近更新 更多