以下是個人對PDV的粗淺總結(jié),希望各位高手補充指正。
個人認為可以把PDV想象成一排用于存放變量值的盒子。每個盒子代表一個變量。 提交一個DATA步后,SAS會對這個DATA步進行編譯,然后執(zhí)行。 首先,PDV是在DATA步的編譯階段生成的。(編譯會進行語法檢查并創(chuàng)建一排整齊擺放的”盒子”); 然后,在DATA步的執(zhí)行階段,根據(jù)不同語句對PDV中變量的值進行清空或更改。(將盒子清空或換上新的物品); 最后,在RUN;語句或者OUTPUT;語句將PDV中變量的當(dāng)前值輸出到目標數(shù)據(jù)集中。KEEP,DROP語句或KEEP=,DROP=數(shù)據(jù)集選項會影響輸出到目標數(shù)據(jù)集中變量的個數(shù)。(如果沒有KEEP/DROP,將新建變量和數(shù)據(jù)集變量對應(yīng)的盒子搬出到目標數(shù)據(jù)集;如果只有KEEP,則只搬KEEP指定的盒子;如果只有DROP,則不搬DROP指定的盒子;如果KEEP/DROP同時存在,則只搬KEEP-DROP后剩下的盒子) DATA步中所涉及到的所有的變量,包括新創(chuàng)建的、從其他數(shù)據(jù)集讀取的(SET)、以及自動生成的變量。自動生成的變量包括:_ERROR_,_N_; 或是FIRST.VAR,_IORC_等由某個語句或選項所自動產(chǎn)生的變量。默認情況下,自動生成的變量不會輸出到目標數(shù)據(jù)集中。 PDV中變量按照先來后到的原則,是根據(jù)其在DATA步中第一次出現(xiàn)的位置決定整個PDV中的變量順序。同樣,這是在DATA步的編譯階段確定的。(在SET語句中,數(shù)據(jù)集選項IN=所指定的變量會在數(shù)據(jù)集變量之前)PUT _ALL_; 語句會將PDV中所有的變量按照其在PDV中的順序輸出到log中。
在PDV中共有13個變量,包括兩個新創(chuàng)建的(aaa,bbb),5個數(shù)據(jù)集中的,6個自動生成的(in1,first.name,last.name,in2, _error_, _n_)。 順序為:aaa, in1, name, sex, first.name, last.name, bbb, in2, age, weight, height, _error_,_n_。 關(guān)于PDV中變量值的RETAIN 一般情況下,DATA步的執(zhí)行是一個循環(huán)的過程,也就是SAS運行到DATA步最后一句后會默認回到DATA語句繼續(xù)執(zhí)行。在回到DATA語句再次執(zhí)行這個DATA步的代碼的時候,就會涉及到是否對PDV中變量已有的值清空,這就是RETAIN要做的。 (這里用“一般情況下”,是因為有些情況下,SAS不會回到DATA語句,而是在RUN;語句就結(jié)束了。如:
回到PDV: a. 在DATA步剛開始執(zhí)行的時候: 自動生成變量會被附上初始值:_N_=1, _ERROR_=0,FIRST.VAR=1, LAST.VAR=1, 等等; 如果RETAIN語句對某變量設(shè)置了的初始值,則對應(yīng)的變量被設(shè)為指定的值; SUM語句(如a 1;)的變量會被初始化為0; 其他的變量,包括新建變量和SET的數(shù)據(jù)集對應(yīng)的變量都會被設(shè)為空值。 b. 當(dāng)SAS執(zhí)行過程中再次回到DATA語句時: 自動生成變量的值會被retain; 如變量來自RETAIN語句、SUM語句、或數(shù)據(jù)集中,則變量值會被retain; 其他的變量會被置空。 例如,可以根據(jù)下面DATA步所產(chǎn)生的log來判斷變量的retain情況:
|
|