非明示添字配列と do over LOOPの利用

ARRAYステートメントを初めて覚える時、
 
array 配列名 {配列要素数} 以下、$や長さや配列要素内容や初期値といった感じで、

とりあえず array 配列名 {配列要素数} までは鉄板と覚えてしまいがちですが
それは正確には明示添字配列の定義法であり、
実は{配列要素数}を省略して定義することができます。

例えば、以下のようなデータセットがあっととします

data Q1;
X=1;Y=2;Z=3;output;
run;





XからZまでを配列として、配列要素全てに+1をする場合、
書き方はいくらでもありますが、例えば

data A0;
 set Q1;
 array AR{*} X--Z;
 do i=1 to dim(AR);
  AR{i}=AR{i}+1;
 end;
 drop i;
run;





と書いたとします。
ここでは{*}と要素数を定数にしていませんが、do to loopの終端条件で
dim関数でARの要素数を取得しているので問題ありません。

ただ、よくよく考えると、配列を定義して、その配列全部におんなじ処理を一括で
かける今回のような場合、要素番号ってあんまり役にたってません。

そこで実は以下のようなコードが成立します。

data A1;
 set Q1;
 array AR X--Z;
 do over AR;
  AR=AR+1;output;
 end;
run;

結果は同じです。
 array AR X--Z;と要素番号定義をすっとばしています。
 do i=1 to dim(AR);が do over AR;となっています。do overは全要素に対して順にループするという
 do i=1 to dim(AR);と同義になります。

ちなみに明示添字配列で定義した配列にdo overを使用すると以下のエラーメッセージです。




「ERROR: 明示添字配列に DO OVER ステートメントは使用できません。」

ただし、たとえば以下のコードのように非明示添字配列で定義しても
要素番号処理は裏でちゃんと勝手に行われているので

data A2;
 set Q1;
 array AR X--Z;
  A=AR{1};
  B=dim(AR);
run;




エラーになったりはしません。


4 件のコメント:

  1. いつもブログを読んで勉強させてもらってます。現在自分が所属する部署ではSAS上でsort summary を行うことが多いため、そのための簡単なマクロを設定したいと思っています。sortではなくindexを設定する方が早いのでindexを活用していますが、index設定の際のキーが複数の場合と一つの場合の両方で使えるマクロは作成するのによいアイデアはありませんか?今の自分の知識では以下のマクロが精一杯です。

    %macro sum(a,b,c,x,y);
    /*
    a ソートキー
    bサムキー
    c ソート項目が単数なら1
    x インプットデータ
    y アウトプットデータ
    */
    %if &c=1 %then %do;
    proc datasets nolist;
    modify &x;
    index delete &a;
    index create &a;
    run;
    %end;

    %if &c^=1 %then %do;
    proc datasets nolist;
    modify &x;
    index delete keyZZZ;
    index create keyZZZ(&a);
    run;
    %end;

    proc summary data=&x noprint;
    var &b;by &a;
    output out =&y
    sum=&b ;
    run;
    %mend sum;

    返信削除
    返信
    1. コメント有難うございます。遅い時間までお疲れ様です。インデックスの実用例をまだ多く知らなかったので、貴重な情報をいただきまして誠に有難うございます。抽出する際の効率化ばかり考えていて、byでまわすためのインデックスが盲点になってました。勉強になります。あまり大したアイデアにならなかったのですが、次の投稿にあげさせていただきました。

      削除
  2. こんにちは。

    非明示添字配列の醍醐味というか面白いところは、
    特に「ARRAY 配列名(変数名)」という書き方ですよね。
    最近適当に書いてて発見して面白いと思ったんですが、常識なんでしょうか?

    こんなデータがあったとき、

    data DT1;
    X1="a";X2="b";X3="c"; VARNO=1; output;
    X1="d";X2="e";X3="f"; VARNO=3; output;
    run;

    ↓こんな感じで、要素番号を変数「NO」に勝手に入れてくれるのが面白いと思いました。

    data DT2;
    set DT1;
    array AR(NO) X:;
    do over AR;
    VAL=AR;
    output;
    end;
    drop X:;
    run;

    あと、こんな書き方も。

    data DT3;
    set DT1;
    array AR(VARNO) X:;
    VAL = AR;
    run;

    返信削除
  3. 有難うございます!
    いや、これ多分、両方初見でしたね、、。特に下の書き方は、絶対でてこない気がします。array、もっと機能追加された上で、わかりやすいリファレンスでないですかね~
    。テクニカルニュースの特集でいいから、一度整理して勉強したいです。

    返信削除