Dplyr cumsum与约束列

时间:2017-07-13 17:28:08

标签: r dplyr

我有一个问题,我需要生产一定数量的单位,但有容量限制。 所以我有一个数据框,两列,一个用于我可以构建的容量,每一行是一周和一个分配列,这是交易消耗了多少。 分配不能大于容量。

见下文交易金额为10。

df <- data.frame(capacity = c(2,3,0,1,2,3),
                     allocation = c(0,0,0,0,0,0))

capacity allocation
       2          0
       3          0
       0          0
       1          0
       2          0
       3          0

amount <- 10

dfb <- data.frame(capacity = c(2,3,0,1,2,3),
                      allocation = c(2,3,0,1,2,2))

这是我想要的结果

capacity allocation
       2          2
       3          3
       0          0
       1          1
       2          2
       3          2

我尝试了以下但是它没有给我正确答案

dfb <- df %>% 
           mutate(deal = 0) %>%
           mutate(deal = if_else(row_number(deal) == 1, amount, 0)) %>%
           mutate(deal = cumsum(deal - pmin(capacity, deal)))

4 个答案:

答案 0 :(得分:3)

分两步执行:

df %>% 
    # allocate cumulatively and truncate if the total surpass the amount
    mutate(allocation = pmin(cumsum(capacity), amount), 
           # calculate the final allocation based on the cumulative allocation
           allocation = allocation - lag(allocation, default = 0))

#  capacity allocation
#1        2          2
#2        3          3
#3        0          0
#4        1          1
#5        2          2
#6        3          2

答案 1 :(得分:3)

这是另一种选择......

dfb <- df %>% mutate(allocation=pmin(capacity,
                     pmax(0, amount-lag(cumsum(capacity), default = 0))))

dfb
  capacity allocation
1        2          2
2        3          3
3        0          0
4        1          1
5        2          2
6        3          2

答案 2 :(得分:2)

与@ Psidom的答案类似,使用基础R

df <- data.frame(capacity = c(2,3,0,1,2,3),
                 allocation = c(0,0,0,0,0,0))
amount <- 10

df$allocation <- diff(pmin(cumsum(c(0, df$capacity)), amount))

结果

> df
  capacity allocation
1        2          2
2        3          3
3        0          0
4        1          1
5        2          2
6        3          2

答案 3 :(得分:0)

这是我的解决方案:

dfb <- df %>% mutate(deal=ifelse(cumsum(capacity)<amount,capacity,capacity+amount-cumsum(capacity)))