在R中根据设定的限制赋值

4

我有一个店铺列表,其中存有不同商品的数量,还有一个仓库,里面存放着这些商品 - 这两个数据框是分开的。

Article <- c('a','b','a','b','c','d')
forecast <- c( 1,5,80,10,100,1000)
StoreID <- c(1,1,2,2,3,4)
StoreData <- data.frame(StoreID, Article, Order)

类似这样的:

StoreData
StoreID Article forecast
1       a        1
1       b        5
2       a       80
2       b       10
3       c      100
4       d     1000

仓储数据如下:

Stock <- c(10,11,12,100)
WarehouseData <- data.frame(Article, Stock)

WarehouseData
Article Stock
a    10
b    11
c    12
d   100

我的目标是有一个采购订单列。逻辑应该如下:对于 StoreData 表中的每一行,我必须查看 Warehouse 中物品的库存数量,如果足够,则批准 fcst,否则只批准可用数量。我的问题是,在批准数量时,可用库存在减少,我不知道如何考虑这个因素。
期望的结果如下:
StoreData
StoreID Article forecast PO
1       a        1        1
1       b        5        5
2       a       80        9
2       b       10        6
3       c      100       12
4       d     1000      100

请问有人知道如何正确地做到这一点吗?


为什么a的第一个观测值的PO等于1(与预测相同),但c和d的第一个观测值与WarehouseData中的Stock相同? - Sotos
你需要按顺序进行商店ID吗?例如,如果商店1对某个商品的预测用光了所有库存,则不会填充商店2的订单? - Raad
@Sotos,这正是关键所在 - 如果仓库中有足够的数量,我必须在此列中批准预测。如果库存不足,我需要分配仓库中可用的库存,而不是预测。 - Pavel M
啊...好的,这很有道理。 - Sotos
@NBATrends 你说得没错。 - Pavel M
2个回答

3

这里有另一种使用dplyr的方法:

library(dplyr)
left_join(storeData, WarehouseData, by = "Article") %>% 
  group_by(Article) %>% 
  mutate(PO = ifelse(cumsum(forecast) <= Stock, forecast, 
                     Stock - cumsum(forecast) + forecast)) %>% ungroup

#Source: local data frame [6 x 5]
#
#  StoreID Article forecast Stock    PO
#    (int)  (fctr)    (int) (dbl) (dbl)
#1       1       a        1    10     1
#2       1       b        5    11     5
#3       2       a       80    10     9
#4       2       b       10    11     6
#5       3       c      100    12    12
#6       4       d     1000   100   100

1
请看下面的循环示例:
StoreData$PO <- NA
for (i in 1:nrow(StoreData)) {
  query <- WarehouseData$Article == StoreData[i, "Article"]
  po <- ifelse(StoreData[i, "forecast"] > WarehouseData[query, 2], 
               WarehouseData[query, 2],
               StoreData[i, "forecast"])

  WarehouseData[query, 2] <- WarehouseData[query, 2] - po
  StoreData[i, "PO"] <- po
}

print(StoreData)
# StoreID Article forecast  PO
# 1       1       a        1   1
# 2       1       b        5   5
# 3       2       a       80   9
# 4       2       b       10   6
# 5       3       c      100  12
# 6       4       d     1000 100

这是另一种基于其他解决方案的替代方案,使用基本的R语言实现:
StoreData <- merge(StoreData, WarehouseData)
StoreData$PO <- do.call(c, lapply(split(StoreData, StoreData$Article), function(z) {
  ifelse(cumsum(z$forecast) <= z$Stock, z$forecast, 
         z$Stock - cumsum(z$forecast) + z$forecast) 
}))

以下是我用来重新创建您的数据集的内容,可能会对其他答案有所帮助:

StoreData <- read.table(text = "StoreID Article forecast
                        1       a        1
                        1       b        5
                        2       a       80
                        2       b       10
                        3       c      100
                        4       d     1000", header = T)


Article <- c('a','b','c','d')
Stock <- c(10,11,12,100)
WarehouseData <- data.frame(Article, Stock)

非常感谢。现在我会尝试弄清楚它是如何工作的 :) - Pavel M

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接