根据条件和groupby更新列

Vis*_*pta 3 r dplyr

我的数据是:

Prod   Vend    Capac  Dema   Price
 p1     v2       2      6      1
 p1     v1       3      6      2
 p1     v3       3      6      2
 p2     v1       1      1      1
 p2     v3       2      1      2
 p2     v2       5      1      2
 p3     v1       5      3      3
 p3     v2       3      3      4
 p3     v3       1      3      5
Run Code Online (Sandbox Code Playgroud)

我需要这样的东西:

Prod   Vend    Capac  Dema   Price   Source
 p1     v2       2      6      1       2
 p1     v1       3      6      2       3
 p1     v3       3      6      2       1 
 p2     v1       1      1      1       1
 p2     v3       2      1      2       0
 p2     v2       5      1      2       0
 p3     v1       5      3      3       3
 p3     v2       3      3      4       0 
 p3     v3       1      3      5       0 
Run Code Online (Sandbox Code Playgroud)

我有产品,供应商,供应商(供应商),需求(产品),价格(供应商的产品).我是以最低价格采购产品,但供应商能力是一个约束.也就是说,供应商的选择是通过它引用的价格来完成的,价格按照按产品分组的供应商进行分类.

我正在尝试使用for循环和if else条件,代码变得更加混乱.是否有一种干净的方法来解决它,可能使用plyr?

Fra*_*ank 7

这就是我要做的事情:

library(data.table)
setDT(DT)

DT[order(Price), src := pmin(Capac, pmax(Dema - shift(cumsum(Capac), fill=0), 0)), by=Prod]
Run Code Online (Sandbox Code Playgroud)

我们可以看到它匹配:

   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
Run Code Online (Sandbox Code Playgroud)

逻辑,部分是伪代码:

  • shift(cumsum(Capac), fill=0) 来自更便宜的供应商的容量

  • max(demand - capacity from cheaper, 0) 是供应商的剩余需求

  • min(capacity, residual demand) 来自供应商的是多少来源

.


dplyr类似物:

DT %>% arrange(Price) %>% group_by(Prod) %>% 
  mutate(src = pmin(Capac, pmax(Dema - lag(cumsum(Capac), default=0), 0)))
Run Code Online (Sandbox Code Playgroud)

  • 很干净的方法.+2为此 (2认同)