2014-12-23 52 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;