do_overメソッドとハッシュ反復子オブジェクトの簡単な使い方

490 Views

October 21, 24

スライド概要

[第10回大阪sas勉強会]

profile-image

SAS言語を中心として,解析業務担当者・プログラマなのコミュニティを活性化したいです

シェア

またはPlayer版

埋め込む »CMSなどでJSが使えない場合

関連スライド

各ページのテキスト
1.

do_overメソッドと ハッシュ反復子オブジェクト(hash iterator object) の簡単な使い方 イーピーエス株式会社 森岡 裕

2.

do_over Method ハッシュオブジェクトの重複キーのリスト内を移動します。 ハッシュオブジェクトが単一のキーに対して複数の値を持つ場合、DO_OVERメソッドをDOルー プの反復内で使用して、重複キー間を移動します。DO_OVERメソッドは最初のメソッド呼び出 しでキーを読み込み、キーが最後に到達するまで重複キーリストを移動しつづけます。

3.

data AE; SUBJID="001";AENO="1";output; SUBJID="001";AENO="2";output; SUBJID="001";AENO="3";output; SUBJID="002";AENO="1";output; SUBJID="003";AENO="2";output; run; data CM; SUBJID="001";CMTRT="Drug A";ACNAENO="1,2";output; SUBJID="001";CMTRT="Drug B";ACNAENO="1";output; SUBJID="001";CMTRT="Drug C";ACNAENO="3,2";output; SUBJID="003";CMTRT="Drug D";ACNAENO="2";output; SUBJID="003";CMTRT="Drug E";ACNAENO="1,2";output; run; 有害事象に使われたCMTRTを取得したいと いったケース

4.

data wk1; length SUBJID AENO $200. USED_DRUG $1000.; set AE; if 0 then set CM; if _N_ = 1 then do; declare hash Multidata:’Y’でハッシュオブジェクト内にkeyを重 h1(dataset:"CM",multidata:"Y"); 複して存在させる h1.definekey("SUBJID"); h1.definedata("CMTRT","ACNAENO"); わざと一意にならないkey条件する.AEとつ h1.definedone(); なぐための条件がSUBJIDのみなので. end; call missing(of ACNAENO CMTRT); do while(h1.do_over() = 0); if ^missing(ACNAENO) then do; Keyがある限りfindメソッドが動くイメージ do i = 1 to count(ACNAENO,",") + 1; if AENO = scan(ACNAENO,i,“,”) then USED_DRUG=catx(",", USED_DRUG, CMTRT); end; end; end; keep SUBJID AENO USED_DRUG; run;

5.

・・・・ do while(h1.do_over() = 0); ・・・・ end; ハッシュオブジェクト Setしたデータセットの1obsごとにkey(SUBJID)でハッシュオブ ジェクト内が検査され該当するすべてのSUBJIDをもつハッシュ内の データがfindメソッドで取得される.ヒットしなくなるまで.

6.

data wk1; length SUBJID AENO $200. USED_DRUG $1000.; data wk1; set AE; length SUBJID AENO $200. USED_DRUG $1000.; if 0 then set CM; set AE; if _N_ = 1 then do; if 0 then set CM; declare hash h1(dataset:"CM",multidata:"Y"); if _N_ = 1 then do; h1.definekey("SUBJID"); declare hash h1.definedata("CMTRT","ACNAENO"); h1(dataset:"CM",multidata:"Y"); h1.definedone(); h1.definekey("SUBJID"); end; h1.definedata("CMTRT","ACNAENO"); call missing(of ACNAENO CMTRT); h1.definedone(); if h1.find()= 0 then do; end; if ^missing(ACNAENO) then do; call missing(of ACNAENO CMTRT); do i = 1 to count(ACNAENO,",") + 1; do while(h1.do_over() = 0); if AENO = scan(ACNAENO,i,“,”) then if ^missing(ACNAENO) then do; USED_DRUG=catx(",", USED_DRUG, CMTRT); do i = 1 to count(ACNAENO,",") + 1; end; if AENO = scan(ACNAENO,i,“,”) then end; USED_DRUG=catx(",", USED_DRUG, CMTRT); do while(h1.find_next() = 0); end; if ^missing(ACNAENO) then do; end; do i = 1 to count(ACNAENO,",") + 1; end; if AENO = scan(ACNAENO,i,",") then keep SUBJID AENO USED_DRUG; USED_DRUG=catx(",", USED_DRUG, CMTRT); run; end; end; end; do_overメソッドの機能はfindメソッド+find_nextメソッ end; ドをあわせたようなもので,これによって処理の冗長性 keep SUBJID AENO USED_DRUG; run; が排除される

7.

ハッシュ反復子オブジェクト Hash Iterator Object ハッシュ反復子オブジェクトにより、ハッシュオブジェクトのデータを前向 きまたは逆向きのキー順序で取得できます。 ハッシュオブジェクト ハッシュ反復子オブジェクト key Data key Data key Data key Data key Data key Data ハッシュオブジェクトのメソッドはあくまでkeyに縛られた対象範囲しかも てないがハッシュ反復子オブジェクトは内部を自由にポインタ移動できる

8.

data dm; SUBJID="001";AGE=36;output; SUBJID="002";AGE=40;output; SUBJID="003";AGE=52;output; run; data AGE_Criteria; L_LIMIT=20;U_ULIMIT=29;cat="20 - 29";output; L_LIMIT=30;U_ULIMIT=39;cat="30 - 39";output; L_LIMIT=40;U_ULIMIT=49;cat="40 - 49";output; L_LIMIT=50;U_ULIMIT=59;cat="50 - 59";output; run; データセットとしてCriteriaの情報があって それをもって抽出や計算する場合,対象のデータセット とCriteriraの中に直接的なリンクがなく 直積での処理となる

9.
[beta]
ハッシュオブジェクトを依り代にして,ハッシュ反復子
オブジェクトは定義される
declare hiter 反復子オブジェクト名(‘基となるハッシュ
オブジェクト名’)

data wk1;
set dm;
if 0 then set AGE_Criteria;
if _N_ = 1 then do;
declare hash h1(dataset:"AGE_Criteria",ordered:"Y");
declare hiter hi1('h1');
h1.definekey(all:"Y");
h1.definedone();
Firstメソッドで最初の位置にポインタ移動
end;
if hi1.first() = 0 then do;
if L_LIMIT <= AGE <= U_ULIMIT then AGECAT=cat;
do while ( hi1.next()=0);
if L_LIMIT <= AGE <= U_ULIMIT then AGECAT=cat;
end;
end;
keep SUBJID AGE AGECAT;
Nextメソッドでハッシュ反復子オブジェクト内にレコードがある
限り,順次走査し続ける
run;

10.

最近距離のマッチング処理の時などにハッ シュ反復子オブジェクトはよく使う

11.

data a; set sashelp.class; BMI = divide(WEIGHT* 703, HEIGHT**2 ); run; ポンドとインチなのでBMIの計算式が普段と違う 同じクラスの中で自分と最もBMIの近い人を選ぶ処理を考える

12.
[beta]
%macro bmi();
_BMI = divide(_WEIGHT* 703, _HEIGHT**2 );
diff=abs(round(BMI,10**-10) - round(_BMI,10**-10));
if NAME ne _NAME and ( missing(mindiff) or diff <
mindiff) then do;
Neighbour=_NAME;
mindiff=diff;
data wk2;
NBMI=_BMI;
length NAME _NAME Neighbour $12. _HEIGHT _WEIGHT 8.;
end;
set sashelp.class;
%mend;
if _N_ = 1 then do;
declare hash h1(dataset:"sashelp.class(reNAME=(NAME=_NAME
HEIGHT=_HEIGHT WEIGHT=_WEIGHT))",ordered:"Y");
declare hiter hi1('h1');
h1.definekey(all:"Y");
h1.definedone();
end;
BMI = divide(WEIGHT* 703, HEIGHT**2 );
mindiff=.;
Neighbour="";
call missing(of _NAME _HEIGHT _WEIGHT _BMI);
if hi1.first() = 0 then do;
%bmi();
do while ( hi1.next()=0);
%bmi();
end;
end;
keep NAME Neighbour BMI NBMI mindiff;

run;

13.

自分以外の人と総当たりでスコアを比較して 差の絶対値が小さければ入れ替えるということを繰り返す もっともシンプルな総当たり探索.

14.

ハッシュ反復子オブジェクトでのみ有効なメソッド FIRSTメソッド 基となるハッシュオブジェクト内の最初のデータ項目を返して,そこにポインタ移動 LASTメソッド 基となるハッシュオブジェクト内の最後のデータ項目を返してそこにポインタ移動 NEXTメソッド ハッシュ反復子オブジェクト(基のハッシュオブジェクト)において,現在位置の次の項目を返してそこに ポインタ移動 PREVメソッド ハッシュ反復子オブジェクト(基のハッシュオブジェクト)において,現在位置の前の項目を返してそこに ポインタ移動 SETCURメソッド 基となるハッシュオブジェクトのkeyに基づいて,ポインタの位置を移動.値は返さない

15.

FIRST メソッド PREV メソッド Data step; rc = setcur(); Run; SETCUR メソッド 特定の位置にポインタを 動かす key Data key Data key Data key Data key Data key Data NEXT メソッド LAST メソッド

16.

結論 重複キーで設定したハッシュオブジェクトにおけるdo_overメソッドについて説明し そこから,さらにキーの制約を受けずにハッシュオブジェクト内を自由にポインタ移動できる ハッシュ反復子オブジェクトの基本を説明した 例示はいずれも単純なものであるが,工夫次第でいくらでも 複雑な処理の単純化,高速化が 可能なので,ぜひ勉強してみてください

17.

ご清聴ありがとうございました Thank you for your attention.