SAS筆記(2) RETAIN語句


本文重點:

  • 使用RETIAN,INPUT在每次循環執行時保留上一次PDV中的變量值。
  • SUM語句和SET語句會自動RETAIN變量。

1. RETAIN語句

1.1 Example 1

先來看看在DATA步不使用和使用RETAIN語句的差異

沒有使用RETAIN:

DATA WITHOUT_1;
   PUT "Before the INPUT statement:  " _ALL_;
   INPUT X @@;
   PUT "After the INPUT statement:   " _ALL_ /;
DATALINES;
1 2 . 3
;

a1

使用RETAIN:

DATA WITH_1;
   RETAIN X;
   PUT "Before the INPUT statement:  " _ALL_;
   INPUT X @@;
   PUT "After the INPUT statement:   " _ALL_ /;
DATALINES;
1 2 . 3
;

a2

注意比較兩段代碼的輸出紅色矩形的內容,結合上一篇博客里講的PDV,不難發現:

  • 不使用RETAIN,INPUT在每次循環執行時會把PDV中的變量值清空,即置為(.)。
  • 使用RETIAN,INPUT在每次循環執行時保留上一次PDV中的變量值。

實際上,上面這個例子里數據集WITHOUT_1和WITH_1的內容是一樣的,下面來看一個必須要用RETAIN的例子。

1.2 Example 2

考慮這樣一種場景:我們的數據集中有缺失值,我們想用該缺失值的前一個非缺失值來填補該缺失值,比如我們的數據是1,2,.,3填補后是1,2,2,3。
這在SAS中很好處理,我們只需要用一個變量記住上一個非缺失值即可:

DATA WITHOUT_2;
   PUT "Before INPUT:      " _ALL_ ;
   INPUT X @@;
   IF X NE . THEN OLD_X = X;
   ELSE X = OLD_X;
   PUT "After assignment:  " _ALL_ /;
DATALINES;
1 2 . 3
;

遺憾的是這段代碼並沒有實現我們的目的
a3
查看日志,問題就很明顯了,因為沒有使用RETAIN,所以在數據步的每一次循環開始時,PDV中的變量均被置空,所以OLD_X每一次都是空:

a4

既然想讓OLD_X記住DATA步每次迭代的前一個值,我們RETAIN住OLD_X即可:

DATA WITH_2;
   RETAIN OLD_X;
   PUT "Before INPUT:      " _ALL_ ;
   INPUT X @@;
   IF X NE . THEN OLD_X = X;
   ELSE X = OLD_X;
   PUT "After assignment:  " _ALL_ /;
DATALINES;
1 2 . 3
;

a5

1.3 Example 3

考慮這樣一種場景:在我們讀入數據的時候,我們想給每個數據加一個順序的行號,第一條觀測是1,第二條觀測是2,依次到最后一條觀測。

下面用RETAIN語句實現:

DATA WITH_3;
   RETAIN SUBJECT 0;
   PUT "Before the INPUT statement: " _ALL_ ;
   INPUT X @@;
   SUBJECT = SUBJECT + 1;
   PUT "After the INPUT statement: " _ALL_ /;
DATALINES;
1 3 5
;

RETAIN SUBJECT 0;表示在DATA步的每一次迭代時RETAIN住SUBJECT這個變量,不要將其置為空,“0”表示SUBJECT的初始值。

上面這段代碼,可以利用SAS中的SUM語句進行簡化:

DATA WITHOUT_4;
PUT "Before the INPUT statement: " _ALL_ ;
INPUT X @@;
SUBJECT 
+ 1;
 /* SUM statement */ 
PUT "After the INPUT statement: " _ALL_ /;
DATALINES;
1 3 5
;

注意到SUM語句的作用:

  1. 不需要顯示地用“=”賦值
  2. 不需要顯示地初始化SUBJECT,它會自動初始化為0
  3. 不需要顯示地RETAIN,它會自動RETAIN變量

其實,如果你還記得上一篇博客中我們在講PDV時提到的自動變量_n_,這段代碼可以更簡潔:

DATA USE_n_;
PUT "Before the INPUT statement: " _ALL_ ;
INPUT X @@;
n
=
_n_; 
PUT "After the INPUT statement: " _ALL_ /;
DATALINES;
1 3 5
;

1.4 Example4

上一個例子中我們發現SUM語句會自動RETAIN變量,其實SAS中的SET語句也會自動RETAIN變量:

DATA ONE;
   INPUT X Y;
DATALINES;
1 2
;
DATA TWO;
   IF _N_ = 1 THEN SET ONE;
   PUT "Before INPUT statement: " _ALL_;
   INPUT NEW;
   PUT "After INPUT statement: " _ALL_ / ;
DATALINES;
3
4
5
;

a6

看一下日志,就發現SET的確自動RETAIN了變量X,Y。最開始,_N_=1,將X=1,Y=2讀入,然后_N_=2,_N_=3等后面的每一步,粉色框里的X,Y值並沒有在DATA步的每次迭代中被置空。

a7

 

參考資料:《Longitudinal Data and SAS: A Programmer's Guide》


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM