【问题标题】:Creating a vector containing total quantities sold per delivery term创建一个包含每个交货期销售总量的向量
【发布时间】:2015-08-26 11:40:31
【问题描述】:

请看下面的简化表格。我希望每个产品都有一个包含每个交货时间内销售数量的向量。交货时间定义为 4 天。因此,如果我们查看产品 A,我们会看到它从 2015 年 3 月 12 日开始,在第一个交货期(直到 2015 年 7 月 12 日)内,它已售出 4 个数量。第二个交货期从 2012 年 8 月开始/15 并于 2015 年 12 月 12 日结束。因此,在此期间售出 1 个数量。以下交货期限从 2015 年 13 月 12 日开始,到 2015 年 12 月 17 日结束。在此期间没有售出数量,因此在此期间,向量的值必须为 0。在最后一个期间,最终售出 2 个产品。所以基本上这里的问题是关于没有产品销售的时期的信息丢失了。

关于如何使用 R 创建我想要的矢量有什么想法吗?我一直在考虑 for 或 while 循环,但这些似乎没有给出要求的结果。请注意,代码必须适用于包含 1000 多个产品类别的真实数据集,因此必须以一种方式“自动化”。

如果有人能指出我正确的方向,我将不胜感激。

Product    Quantity     Date      

A          1            03/12/15  
A          2            04/12/15  
A          1            05/12/15  
A          1            08/12/15  
A          1            17/12/16  
A          1            18/12/16  
B          1            19/12/15  
B          2            10/05/15  
B          2            11/05/15  
C          1            01/06/15  
C          1            02/06/15  
C          1            12/06/15  

【问题讨论】:

  • 感觉这种问题已经有人回答了……
  • 搜索data aggregation [r]
  • 请提供一个可重现的示例,说明输出的具体内容。如果您需要任何提示,请查看here

标签: r loops


【解决方案1】:

假设 dt 是您提供的数据集。如果您逐步运行它(并且可能使用更简单的数据集),您将更好地理解该过程。

library(lubridate)
library(dplyr)


# create date time columns
dt$Date = dmy(dt$Date)


dt %>% 
  group_by(Product) %>% 
  do(data.frame(days = seq(min(.$Date), max(.$Date), by="1 day"))) %>%     # create all combinations between product and days
  mutate(dist = as.numeric(difftime(days,min(days), units="days"))) %>%    # create distance of each day with min date
  ungroup() %>%
  left_join(dt, by=c("Product"="Product","days"="Date")) %>%              # join info to get quantities for each day
  mutate(Quantity = ifelse(is.na(Quantity), 0, Quantity),                # replace NAs with 0s
         id = floor(dist/5 + 1)) %>%                                    # create the 4 period id
  group_by(Product, id) %>%
  summarise(Sum = sum(Quantity),
            min_date = min(days),
            max_date = max(days)) %>%
  ungroup


#    Product id Sum   min_date   max_date
# 1        A  1   4 2015-12-03 2015-12-07
# 2        A  2   1 2015-12-08 2015-12-12
# 3        A  3   0 2015-12-13 2015-12-17
# 4        A  4   0 2015-12-18 2015-12-22
# 5        A  5   0 2015-12-23 2015-12-27
# 6        A  6   0 2015-12-28 2016-01-01
# 7        A  7   0 2016-01-02 2016-01-06
# 8        A  8   0 2016-01-07 2016-01-11
# 9        A  9   0 2016-01-12 2016-01-16
# 10       A 10   0 2016-01-17 2016-01-21
# ..     ... .. ...        ...        ...

输出的第一行告诉您,对于产品 A,在前 4 天期间(id = 1),您总共有 4 个数量,期间从 3/12 到 7/12。

【讨论】:

    【解决方案2】:

    我建议使用 {dplyr} 的 summarise()、mutate() 和 group_by() 函数。 group_by() 按所需变量(在您的情况下 - 产品和交付期限)对您的数据进行分组,mutate() 允许对分组列进行操作,并且 summarise() 对这些组应用汇总函数(在您的情况下为 sum(Quantity))。

    这就是它的外观:

    将日期转换为正确的格式:

    library(dplyr) df=tbl_df(df) df$Date=as.Date(df$Date,format="%d/%m/%y")

    计算交货条款

    df=group_by(df,Product) %>% arrange(Date) df=mutate(df,term=1+unclass((Date-min(Date)))%/%4)

    按产品和术语分组并计算数量总和:

    df=group_by(df,Product,term) summarise(df,sum=sum(Quantity))

    【讨论】:

      【解决方案3】:

      这是base R的方式:

      df$groups <- ave(as.numeric(df$Date), df$Product, FUN=function(x) {
        intrvl <- findInterval(x, seq(min(x), max(x),4))
        as.numeric(factor(intrvl))
        })
      df
      #    Product Quantity       Date groups
      # 1        A        1 2015-12-03      1
      # 2        A        2 2015-12-04      1
      # 3        A        1 2015-12-05      1
      # 4        A        1 2015-12-08      2
      # 5        A        1 2016-12-17      3
      # 6        A        1 2016-12-18      3
      # 7        B        1 2015-12-19      2
      # 8        B        2 2015-05-10      1
      # 9        B        2 2015-05-11      1
      # 10       C        1 2015-06-01      1
      # 11       C        1 2015-06-02      1
      # 12       C        1 2015-06-12      2
      

      日期应转换为日期类之一。我选择了as.Date。当它转换为数字时,输出将是从指定日期开始的天数。从那里,我们可以按 4 天为增量进行分组。

      数据

      df$Date <- as.Date(df$Date, format="%d/%m/%y")
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-04-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-05-20
        • 2019-04-18
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多