2015-07-04 134 views
1

好吧,這似乎是一件非常簡單的事情,但我無法解釋sas datastep中的「通過聲明」是在做什麼。我知道什麼時候需要使用它,但我不確定它在做什麼。什麼是在sas數據步驟中真正做的陳述?

在下面的例子中,我明白了first.var和last.var的虛擬sas列是什麼時候它具有它所做的值。 By語句圍繞var初始和金屬創建這些虛擬列?然後sas正在掃描整個數據集一次?

data jewelers ; 
    input id initial $ metal $ ; 
datalines; 
456 D Gold 
456 D Silver 
123 L Gold 
123 L Copper 
123 L PLatinum 
567 R Gold 
567 R Gold 
567 R Gold 
345 A Platinum 
345 A Silver 
345 A Silver 
; 

proc sort ; 
    by initial metal ; 
run; 

data dups; 
    set jewelers ; 
    by initial metal ;       
    if not (first.metal and last.metal) then output; 
run; 

如果我PROC打印的DUP我想到這一點:

567 R Gold 
567 R Gold 
567 R Gold 
345 A Silver 
345 A Silver 
+0

在您的示例中,'first.id'和'last.id'未初始化,因爲它們不出現在'by'語句中。要查看創建了哪些隱藏變量,請在'by'語句後面添加'put _all_;'語句。 (只對小數據集執行此操作,因爲它有可能填滿日誌)。 – mjsqu

回答

2

正如您所承認,SAS在你by語句在創建每個byvar自動變量first.byvarlast.byvar。從set語句中讀取的記錄在SAS將它們移動到PDV(程序數據向量 - 在輸出之前在每行中執行數據步驟邏輯)之前將保存在緩衝區中,因此SAS可以預見下一個記錄緩衝區來查看是否有任何分支已經改變,並且爲當前在PDV中的行設置last.byvar = 1

我可以看到你說你期望什麼和你在dups數據集中得到的唯一區別是記錄的順序 - 因爲你已經按初始值和金屬排序,​​記錄在R Gold記錄。

如果您希望在保留原始行順序的同時獲得這兩個變量的重複值,那麼您需要記下原始記錄順序,並在第二個數據步驟後將您的重複數據集重新排序。

0

SAS基本上將當前記錄與前一個和後一個記錄進行比較以計算FIRST。和最後。標誌。如果你願意,你可以推出自己的產品。

data test ; 
    set jewelers end=eof; 
    by initial metal ; 
    if not eof then 
     set jewelers (firstobs=2 keep=initial metal 
        rename=(initial=next_initial metal=next_metal)) 
    ; 
    first_initial = (_n_=1) or (initial ne lag(initial)); 
    last_initial = eof or (initial ne next_initial) ; 
    first_metal = first_initial or (metal ne lag(metal)) ; 
    last_metal = last_initial or (metal ne next_metal); 
    put/(initial metal) (=); 
    put (first:) (=); 
    put (last:) (=); 
run;