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