Вот решение dplyr
, позволяющее избежать циклов:
df = read.table(text = "
facility_abbr itemid need_qty rank available_qty
7 NORW 000643 8 1 40
8 CARN 000643 16 2 40
9 NVMC 000643 24 3 40
10 SEBT 000643 24 3 40
11 SNEC 000643 32 5 40
12 SEMC 000643 96 6 40
13 STAN 000643 784 7 40
130 HFAD 034199 35 1 8
131 EAST 034199 40 2 8
132 NVMC 034199 110 3 8
133 HFHH 034199 113 4 8
134 CARN 034199 182 5 8
", header=T)
library(dplyr)
df %>%
group_by(itemid) %>%
mutate(leftover = available_qty - cumsum(need_qty),
allocated = case_when(leftover < 0 & row_number() == 1 ~ available_qty,
leftover < 0 & row_number() > 1 ~ lag(leftover),
TRUE ~ need_qty),
allocated = ifelse(allocated < 0, 0, allocated),
leftover = ifelse(leftover < 0, 0, leftover)) %>%
ungroup()
# # A tibble: 12 x 7
# facility_abbr itemid need_qty rank available_qty leftover allocated
# <fct> <int> <int> <int> <int> <dbl> <dbl>
# 1 NORW 643 8 1 40 32 8
# 2 CARN 643 16 2 40 16 16
# 3 NVMC 643 24 3 40 0 16
# 4 SEBT 643 24 3 40 0 0
# 5 SNEC 643 32 5 40 0 0
# 6 SEMC 643 96 6 40 0 0
# 7 STAN 643 784 7 40 0 0
# 8 HFAD 34199 35 1 8 0 8
# 9 EAST 34199 40 2 8 0 0
#10 NVMC 34199 110 3 8 0 0
#11 HFHH 34199 113 4 8 0 0
#12 CARN 34199 182 5 8 0 0