2014-09-04 74 views
1

我如何執行數據集中最後n個觀測值的計算 例如,如果我有10個觀測值,我想創建一個變量來總結最後5個值另一個變量。請不要暗示我滯後5次或使用模塊(N)。我需要一個比這更優雅的解決方案。我如何執行最後n個觀測值的計算

下面的代碼alpha是數據集,我有和bravo是我需要的。

data alpha; 
    input lima @@ ; 
    cards ; 
3 1 4 21 3 3 2 4 2 5 
; 
run ; 

data bravo; 
input lima juliet; 
cards; 
3 . 
1 . 
4 . 
21 . 
3 32 
3 32 
2 33 
4 33 
2 14 
5 16 
; 
run; 

非常感謝您!

回答

0

在任何情況下讀取該:) 我解決它,我需要它要解決的途徑。儘管現在我更加好奇兩個(保留和我的解決方案)中的哪一個在計算/處理時間方面更爲優化。

這裏是我的解決方案:

data bravo(keep = var1 summ); 
    set alpha; 
    do i=_n_ to _n_-4 by -1; 
     set alpha(rename=var1=var2) point=i; 
     summ=sum(summ,var2);   
    end; 
run; 
0

我可以提供比較難看溶液:

  1. 運行數據的步驟加入越來越多到每個
  2. 運行sql步驟並添加max(group)的列。
  3. 運行另一個數據步驟,並檢查(2) - (1)中的值是否小於5.如果是,則分配給_num_to_sum_變量(例如)要合計的值,否則將其留空或分配0.
  4. 並且最後執行一個sql步驟sum(_num_to_sum_)並通過對來自(1)的變量進行分組的結果。

編輯:我已經以更緊湊的方式添加了一個實例的概念。

input var1 $ var2; 
cards; 
aaa 3 
aaa 5 
aaa 7 
aaa 1 
aaa 11 
aaa 8 
aaa 6 
bbb 3 
bbb 2 
bbb 4 
bbb 6 
; 
run; 

data step1; 
    set sourcetable; 
    by var1; 
    retain obs 0; 
    if first.var1 then obs = 0; 
    else obs = obs+1; 
    if obs >=5 then to_sum = var2; 
run; 

proc sql; 
    create table rezults as 
     select distinct var1, sum(to_sum) as needed_summs 
     from step1 
     group by var1; 
quit; 
+0

Thnaks,每一個崗位是appriciated。它並不那麼難看。我喜歡;] – criticalth 2014-09-04 11:52:30

+0

Upvoting我的答案然後會很好=) – kaytrance 2014-09-04 12:06:52

+0

它需要15代表:D Sry我是新的。順便說一句,我無法執行您的解決方案。我可以找到一個合適的sql聚合變量,如果_n_可以被5整除然後計數+ 1,那麼這樣做很容易。我想用幾個數組來做,保留或設置命令如果可能 – criticalth 2014-09-04 12:46:12

0

您可以在數據步驟中執行此操作,或者使用SAS/ETS中的PROC EXPAND(如果可用)。

對於數據步驟的想法是,您從累計和(summ)開始,但記錄到目前爲止添加的值的數量(ninsum)。一旦達到5,就開始輸出累計和到目標變量(juliet),並從下一步開始減去滯後5值,僅存儲最後5個值的總和。

data beta; 
    set alpha; 
    retain summ ninsum 0; 

    summ + lima; 
    ninsum + 1; 
    l5 = lag5(lima); 

    if ninsum = 6 then do; 
     summ = summ - l5; 
     ninsum = ninsum - 1; 
    end; 

    if ninsum = 5 then do; 
     juliet = summ; 
    end; 

run; 

proc print data=beta; 
run; 

但是有可以做所有種類的累積,移動窗口等的計算過程:PROC擴大,其中這真的只是一條線。我們只是告訴它在寬度爲5的窗口中計算向後移動的總和,並將前4個觀察值設置爲缺失(默認情況下,它會將您的序列在左側擴展0)。

proc expand data=alpha out=gamma; 
     convert lima = juliet /transformout=(movsum 5 trimleft 4); 
run; 

proc print data=gamma; 
run; 

編輯

如果你想要做更復雜的計算,你需要攜帶在保留變量之前的值。我以爲你想避免這種情況,但在這裏它是:

data epsilon; 
    set alpha; 
    array lags {5}; 
    retain lags1 - lags5; 

    /* do whatever calculation is needed */ 
    juliet = 0; 
    do i=1 to 5; 
     juliet = juliet + lags{i}; 
    end; 

    output; 

    /* shift over lagged values, and add self at the beginning */ 
    do i=5 to 2 by -1; 
     lags{i} = lags{i-1}; 
    end; 
    lags{1} = lima; 

    drop i; 
run; 

proc print data=epsilon; 
run; 
+0

確實非常有用。我不知道proc擴展的功能。儘管這只是一個例子。我打算在考慮到最後的「n」個觀測值的情況下進行非常複雜的計算,並且我想知道是否有辦法做到這一點,而不會在n次滯後不同變量。如果您有任何其他建議,請分享。謝謝:) – criticalth 2014-09-08 16:30:33

+0

我們能以某種方式解決使用DOW循環的問題嗎? – criticalth 2014-09-12 09:05:11

+0

我不知道DOW循環是什麼,但我添加了另一個解決方案,可以對最後的「n」個觀察值進行任意計算。 – Aniko 2014-09-12 13:56:02