R, накопленная сумма в обратном порядке

Допустим, у нас есть две таблицы:

Таблица бюджетов:

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

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 - предыдущие расходы) - оставшийся бюджет
  • min(Расход, остаток бюджета) - текущие расходы

Синтаксис data.table x[i, on=, j, by=.EACHI] это соединение В этом случае j принимает форму v := expr, который добавляет новый столбец к x, Увидеть ?data.table для деталей.


** Ну, "до" в упорядочении таблицы. Я проигнорирую странные перевернутые даты ОП.

Другие вопросы по тегам