2

SAS データ ステップを使用する場合のプログラム データ ベクトルの概念化についてかなり読んだことがありますが、グループ処理がある場合に PDV がどのように機能するかはまだわかりません。たとえば、データセットがある場合olddata

 GROUP   VAL
 A       10
 A        5
 B       20

そして、次のような by ステートメントでデータステップを呼び出します。

data newdata;
set olddata;
by group;
...
run;

次に、コンパイラは PDV に first.group と last.group の 2 つの一時変数を追加します。PDV に関するチュートリアルを読むと、SET ステートメントの最初のパスで PDV が次のようになることがわかります。

_N_    _ERROR_   FIRST.GROUP   LAST.GROUP   GROUP   VAL
  1          0             1            0       A    10

また、観測 1 はグループ A の最後の観測ではないため、LAST.GROUP はゼロです。

ここに私の質問があります: SAS は、これが最後の観測ではないことをどのように知っていますか?

SAS がolddata行ごとに処理している場合、PDV は次の行に新しいグループではなく別のグループ A の観測が含まれていることをどのように認識しますか? つまり、SAS は前または将来の行の情報を使用して変数FIRSTLAST変数を更新する必要があるようですが、その方法はわかりません。BYステートメントが呼び出されたときに PDV が行ごとに値を保持する方法にトリックはありますか?

4

1 に答える 1

1

SAS は、実際には次のレコードを先読みして、LAST.(var) を設定する必要があるかどうかを確認します。残念ながら、それを詳しく説明している記事は見つかりませんでした。http://www.wuss.org/proceedings09/09WUSSProceedings/papers/ess/ESS-Li1.pdfのような論文でさえ、LAST がどのように決定されるかを説明しているだけ であることに少しがっかりしました。

また、SAS は、END= 変数が指定されている場合に設定する必要があるかどうか、およびその他のいくつかのことを事前に確認します。それらを決定するためにメタデータを使用するだけではありません。メタデータを変更せずにレコードを削除または変更でき、それは引き続き機能します。通常の SAS メタデータを持たない SQL テーブルでも、通常の BY グループ処理などを実行できます。

もちろん、FIRST 変数には後読みは必要ありません。結局のところ、それがどこにあったかを覚えています。

編集:これをSAS-Lにクロスポストし、同じ答えを得ました-主題のドキュメントはないようですが、先読みする必要があります. たとえば、http://listserv.uga.edu/cgi-bin/wa?A1=ind1303a&L=sas-l#8を参照してください。

Edit2: SAS-L から、Dan Nordlund がこれを確認する論文にリンクしました。http://support.sas.com/resources/papers/proceedings12/222-2012.pdf

先読みを確認する論文のロジック - データセットから読み取った観測値の数を見てください。

DATA DS_Sample1;          
Input Sum_Var 
Product;     
Cards;                  
100 3                   
100 2                   
100 1                   
;                 
*With BY statement - reads 3 observations even though it stops after 2.;
DATA DS_Sample2;    
  Set DS_Sample1;           
  by Sum_Var;               
  cnt+1; If CNT > 1 then stop;
Run;
*no BY statement - reads 2 observations as expected;
DATA DS_Sample2;    
  Set DS_Sample1;           
  cnt+1; If CNT > 1 then stop;
Run;
* END statement - again, a lookahead;
DATA DS_Sample2;    
  Set DS_Sample1 end=eof;
  cnt+1; If CNT > 1 then stop;
Run;
于 2013-03-05T19:53:56.830 に答える