【问题标题】:Assigning values according to set limits in R根据 R 中的设定限制分配值
【发布时间】:2016-07-02 08:11:35
【问题描述】:

我有一个包含一些不同商品数量的商店列表和一个包含这些商品的仓库 - 这是两个独立的数据框。

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 表中的每一行,我必须查看仓库中商品的库存,如果足够 - 批准 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 = 1 的PO(与预测相同)但第一次观察到 c 和 d 与来自WarehouseDataStock 相同?
  • 您需要按顺序往下走商店ID吗?例如,如果商店 1 的商品预测用完了所有可用库存,那么商店 2 的订单将不会被执行?
  • @Sotos 这正是重点 - 如果仓库中有足够的数量,我必须批准此列中的预测。如果库存较少,我需要从仓库分配可用库存而不是预测
  • 啊...好吧,有道理
  • @NBATrends 你是对的

标签: r while-loop dataframe


【解决方案1】:

这是使用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

【讨论】:

    【解决方案2】:

    请参阅下面的循环示例:

    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)
    

    【讨论】:

    • 非常感谢。现在将尝试弄清楚它是如何工作的:)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多