2014-12-23 50 views
1

我希望获取除产品当前日期以外的先前日期值的总和。下面给出的是数据集。在输出表中,我已经提到了我以前的日期值的总和应该如何。SAS中以前日期值的总和

例如:对于2014年7月27日的日期,我希望按产品级别除当前日期之外的前几个日期的总和。同样,当您在进行7/20/2014的总和时,忽略7/20/2014和7/27/2014的值,然后再取前几个日期的其余值。 此处还有一个例外。例如,当您看到重复项目时,例如7/20/2014和6/8/2014只考虑一个值。

DATE DEALID  PRODUCT  VALUE 
7/27/2014 6575 CLIENT  4 
7/20/2014 16701 CLIENT  6 
7/20/2014 16701 CLIENT  6 
7/13/2014 6601 CLIENT  4 
7/6/2014 10871 SERVICES 5 
6/29/2014 16661 SERVICES 2 
6/22/2014 66757 SERVICES 1 
6/15/2014 77757 SERVICES 5 
6/8/2014 5675 SERVICES 8 
6/8/2014 5675 SERVICES 8 
5/25/2014 5756 SERVICES 4 

输出表

DATE DEALID PRODUCT  VALUE SUMM 
7/27/2014 6575 CLIENT  4 10 
7/20/2014 16701 CLIENT  6 4 
7/20/2014 16701 CLIENT  6 4 
7/13/2014 6601 CLIENT  4 0 
7/6/2014 10871 SERVICES 5 20 
6/29/2014 16661 SERVICES 2 18 
6/22/2014 66757 SERVICES 1 17 
6/15/2014 77757 SERVICES 5 12 
6/8/2014 5675 SERVICES 8 4 
6/8/2014 5675 SERVICES 8 4 
5/25/2014 5756 SERVICES 4 0 

回答

2

普通老式SAS数据步骤usualy更多对于非常具体的要求,它们通常运行得更快。

让我们开始排序像NEO_mental创建数据

data test; 
       infile datalines; 
       format date mmddyy10.; /** Make SAS print dates as a date instead of numbers **/ 
       input date : mmddyy10. 
            Dealid : $ 8. 
            PRODUCT : $10. 
            Value : 8. 
            ; 
datalines; 
7/27/2014 6575 CLIENT  4 
7/20/2014 16701 CLIENT  6 
7/20/2014 16701 CLIENT  6 
7/13/2014 6601 CLIENT  4 
7/6/2014 10871 SERVICES 5 
6/29/2014 16661 SERVICES 2 
6/22/2014 66757 SERVICES 1 
6/15/2014 77757 SERVICES 5 
6/8/2014 5675 SERVICES 8 
6/8/2014 5675 SERVICES 8 
5/25/2014 5756 SERVICES 4 
; 
run; 

要计算运行总,我按升序日期顺序。 我不会删除重复项,因为我在数据步骤中处理它们。

proc sort data=test out=ascendingTest; 
       by Product Date; 
run; 

来了良好的旧数据的步骤,其中我做所有的计算

/** Create a dataset including the running total **/ 
Data summTest; 

       /** Read in the data **/ 
       set ascendingTest; 

       /** Enable things like first.Product and last.Date **/ 
       by Product Date; 

       /** Create the running total **/ 
       /** variables are initialised for each observation (=row) unless you retain them **/ 
       retain Summ; 
       if first.Product then Summ = 0; /** Start over for each product **/ 

       /** Write out the result BEFORE increasing the total **/ 
       output; 

       /** Increase the running total for the later dates **/ 
       if last.Date then Summ = Summ + Value; 
run; 

因为我们没有删除重复的,我并不需要合并,因此,所有我所要做的就是按照降序排序。 注意:如果性能问题,请写'Data summTest/view = summTest。这样数据步骤将不会读取任何数据,只有在排序步骤消耗结果时才会执行计算。 ;

proc sort data=summTest out=final; 
       by Product descending Date ; 
run; 
+0

好的一个!聪明的apporach! +1 – NEOmen

0

好了,我不知道如果多数民众赞成的最佳方式做到这一点。

运行proc sql以获取不同的日期并将它们存储到像date1 - dateN这样的变量中。 另一个proc sql来计算不同日期并将数量存储到一个称为count或变量的变量中。

然后创建一个与原始列和sum列相同的空表,对日期进行循环,将表中日期为<的所有值相加,最后插入结果进入空表。

如果日期过多,则可以使用表格而不是date1-dateN变量。

0

下面是可重复的代码

使用Datalines读取数据集

data test; 
infile datalines; 
input date : mmddyy10. 
     Dealid : $ 8. 
     PRODUCT : $10. 
     Value : 8. 
     ; 
datalines; 
7/27/2014 6575 CLIENT  4 
7/20/2014 16701 CLIENT  6 
7/20/2014 16701 CLIENT  6 
7/13/2014 6601 CLIENT  4 
7/6/2014 10871 SERVICES 5 
6/29/2014 16661 SERVICES 2 
6/22/2014 66757 SERVICES 1 
6/15/2014 77757 SERVICES 5 
6/8/2014 5675 SERVICES 8 
6/8/2014 5675 SERVICES 8 
5/25/2014 5756 SERVICES 4 
; 
run; 

从每个产品

proc sort data=test nodupkey out=test1; 
by PRODUCT date; 
run; 

总结价值的数据集删除重复的日期基于产品(notice nw AY)

proc summary data=test1 nway; 
class PRODUCT; 
var Value; 
output out=test2(drop = _type_ _freq_) 
sum(Value)=Value_summ; 
run; 

排序和合并回原始数据集,并做进一步的计算

proc sort data=test; 
by PRODUCT; 
run; 

proc sort data=test2; 
by PRODUCT; 
run; 
  • 利用滞后,以检查是否有日期
  • 重复检查滞后日期,如果它们相同,那么SUMM将保留先前的值,但是为了避免在连续记录中存在的两个不同产品中的日期相同的情况下,存在'OR'c ondition,这将检查是否在以前的记录产品不同,或者不是,是否有那么它会去的减法,希望是有道理的

data FINAL(drop=date_lag product_lag); 
retain SUMM; 
format date mmddyy10.; 
merge test(in=a) test2(in=b); 
by PRODUCT; 
date_lag=lag(date); 
product_lag=lag(product); 
if date ne date_lag or product ne product_lag then SUMM=SUMM-value; 
run;