2017年12月12日火曜日

HASHオブジェクトで、Key変数毎に最小値・最大値・合計値などを取得する方法


(業務でコピペ利用するための、ほとんど個人的なメモ。)






* Sample Data ;
data DT1;
input NO:$3. SEX:$1. AGE:8.;
cards;
001 F 39
002 M 25
;

NO・・・顧客ID
SEX・・・性別
AGE・・・年齢



data DT2;
input NO:$3. FOOD:$10. BUYDATE:yymmdd10.;
format BUYDATE yymmdd10.;
cards;
001 ORANGE  2017/12/11
001 APPLE   2017/12/13
001 CHERRY  2017/12/10
002 ORANGE  2017/12/15
002 APPLE   2017/12/05
;


NO・・・顧客ID
FOOD・・・購入食品
BUYDATE・・・購入日



上のデータから、顧客ID毎に購入日の最小値を取得したいとします。

data OUT;

    set DT1;

    /* 購入データをHashオブジェクトに格納 */
    if _n_=1 then do;

        length BUYDATE 8.;
        call missing( BUYDATE );

        dcl hash buy( dataset:"DT2", multidata:"y" );
        buy.definekey("NO");
        buy.definedata("BUYDATE");
        buy.definedone();

    end;


    /* Hashオブジェクト内をループして、顧客IDごとの購入日の最小値を取得 */
     rc = buy.find();
     if rc = 0 then MINDATE = BUYDATE;

     do while (rc = 0);
          rc = buy.find_next();
          if rc = 0 then MINDATE = min( MINDATE, BUYDATE );
     end;

     format MINDATE yymmdd10.;
     keep NO SEX AGE MINDATE;
run;





解説

Hashの触りとして以下記事を読むと理解しやすいです。

http://sas-boubi.blogspot.jp/2015/02/hash.html
(SAS忘備録:Hashオブジェクトを使おう)



今回やってる事は、データステップ100万回で解説されてる事なので、以下記事を見て頂くと分かると思います。

http://sas-tumesas.blogspot.jp/2014/07/key-multidata-findnext.html
(データステップ100万回:ハッシュオブジェクトの世界⑧ keyの重複を許容する multidata find_nextメソッド)





かいつまんで解説

  dcl hash buy( dataset:"DT2", multidata:"y" );
  buy.definekey("NO");
  buy.definedata("BUYDATE");
  buy.definedone();

まずはHashオブジェクトの定義から。
データセットDT2をHashオブジェクトに格納し、「multidata:'y'」で、Key値の重複を許しています。
変数NOをKey値、変数BUYDATEをKey値に関連づける変数として定義しています。



  rc = buy.find();
  if rc = 0 then MINDATE = BUYDATE;

findメソッドでHashオブジェクト内をKey値で検索。
該当するKey値があったら、取得したBUYDATEをMINDATEに格納。



  do while (rc = 0);
    rc = buy.find_next();
    if rc = 0 then MINDATE = min( MINDATE, BUYDATE );
  end;

find_nextメソッドで、Hashオブジェクト内の次のレコードを検索。
該当するKey値があったら、取得したBUYDATEをMINDATEと比較し、最小日付をMINDATEに格納。

これをHashオブジェクト内に該当するレコードがなくなるまで、do whileでループしています。




一応今回やってることは、SQLやMEANSとかの方が楽に求められるけど、DATAステップ内で完結できるのが最大のメリットだと思います。


📝注意

記事の中で使用している「_N_」は「サブセット化IF」と一緒に使用すると正しく動かなくなりやすいです。


0 件のコメント:

コメントを投稿