首页 > 解决方案 > 在 SAS 中将数据从数月分解为数周

问题描述

我遇到了一个问题,我有两张桌子,一张在几个月,一张在几周。这是表格的格式:

     Table1

     Customer            Date1          Sales

      1                 Jan2018        1110
      1                 Feb2018        1245
      1                 Mar2018        1320
      1                 Apr2018        1100   
      ...



              Table2

                 Customer              Date2           

                   1                  01Jan2018
                   1                  08Jan2018
                   1                  15Jan2018    
                   1                  22Jan2018
                   1                  29Jan2018
                   1                  05Feb2018
                   1                  12Feb2018       
                   1                  19Feb2018       
                   1                  26Feb2018        
                   1                  05Mar2018
                   ...

我想在 Table2 中为销售额创建一个新列,该列将保存 Table1 中销售额的分类值。我想将销售额除以该月的天数,然后将这些值分配给相应的周数。因此,2018 年 1 月 1 日周的销售额为 (1110/31)*7。处于过渡期的周将从这两个月中获得价值。例如 29Jan2018 在 2018 年 1 月有 3 天,在 2018 年 2 月有 4 天。2018年1月一日销量为1110/31,2018年2月一日销量为1245/28。

所以 2018 年 1 月 29 日的销售额将是 3*(1110/31) + 4*(1245/28)

我想为每个不同的客户这样做。

结果表应该是

               Result Table

              Customer      Date               Sales           
              1             01Jan2018          250.6      i.e (1110/31)*7
              1             08Jan2018          250.6
              1             15Jan2018          250.6 
              1             22Jan2018          250.6 
              1             29Jan2018          282.27
              1             05Feb2018          311.25 
              1             12Feb2018          311.25    
              1             19Feb2018          311.25
              1             26Feb2018          133.39 + 170.32

谢谢!

标签: datesas

解决方案


在 DATA Step 编程中,您将需要一些“FORWARD”数据而不是一些“LAG”数据。可以通过创建对相同数据的视图来模拟前向值,从而开始向前观察(obs = 2)。在理解了重命名语义之后,这只是一些简单的“簿记”问题。

data customer_months;
attrib Customer length=8 Date1 informat=monyy. format=monyy7.; input 
Customer   Date1  Sales; datalines;
1        Jan2018  1110
1        Feb2018  1245
1        Mar2018  1320
1        Apr2018  1100
run;

* week data, also with computation for month the week is in;
data customer_weeks;
attrib Customer length=8 Date2 informat=date9. format=date9.; input
Customer  Date2;
Date1 = intnx('month', Date2, 0);
datalines;
  1      01Jan2018
  1      08Jan2018
  1      15Jan2018
  1      22Jan2018
  1      29Jan2018
  1      05Feb2018
  1      12Feb2018
  1      19Feb2018
  1      26Feb2018
  1      05Mar2018
run;

* next months sales keyed on prior month value;
data customer_next_months_view / view=customer_next_months_view;
  set customer_months;
  Date1 = intnx('month',Date1,-1);  * the month this record will be a forward for;
  rename Sales=Sales_next_month;
  if _n_ > 1;
run;

* merge original and forward data, rename for making clear the variable roles;
data combined;
  length disag_sales 8;

  merge 
    customer_months  (rename=Sales=Sales_this_month)
    customer_next_months_view
    customer_weeks
  ;
  by Date1;

  days_in_this_month = intck('day',intnx('month',Date1,0),intnx('month',Date1,1));
  days_in_next_month = intck('day',intnx('month',Date1,1),intnx('month',Date1,2));

  day_rate_this_month = Sales_this_month / days_in_this_month;
  day_rate_next_month = Sales_next_month / days_in_next_month;

  if Date2 then 
    if month(Date2) = month(Date2+6) then 
      week_days_this_month = 7;
    else
      week_days_this_month = intck('day', Date2, intnx('month', Date2, 1));

  week_days_next_month = 7 - week_days_this_month;

  dollars_this_week_this_month = week_days_this_month * day_rate_this_month;
  dollars_this_week_next_month = week_days_next_month * day_rate_next_month;

  * desired estimated disaggregated sales;    
  disag_sales = sum (dollars_this_week_this_month,dollars_this_week_next_month);
run;

推荐阅读