My data is:
Prod Vend Capac Dema Price
p1 v2 2 6 1
p1 v1 3 6 2
p1 v3 3 6 2
p2 v1
Here's what I would do:
library(data.table)
setDT(DT)
DT[order(Price), src := pmin(Capac, pmax(Dema - shift(cumsum(Capac), fill=0), 0)), by=Prod]
we can see it matches:
Prod Vend Capac Dema Price Source src
1: p1 v2 2 6 1 2 2
2: p1 v1 3 6 2 3 3
3: p1 v3 3 6 2 1 1
4: p2 v1 1 1 1 1 1
5: p2 v3 2 1 2 0 0
6: p2 v2 5 1 2 0 0
7: p3 v1 5 3 3 3 3
8: p3 v2 3 3 4 0 0
9: p3 v3 1 3 5 0 0
The logic, partly in pseudocode:
shift(cumsum(Capac), fill=0)
is capacity from cheaper vendors
max(demand - capacity from cheaper, 0)
is residual demand for the vendor
min(capacity, residual demand)
is how much to source from the vendor
.
The dplyr analogue:
DT %>% arrange(Price) %>% group_by(Prod) %>%
mutate(src = pmin(Capac, pmax(Dema - lag(cumsum(Capac), default=0), 0)))