答えは何種類もありえますが、とりあえず、現実に僕が採用したものを回答例としてあげます。
カラーパレット問題とか適当に名前つけていますが、勝手に僕が作った名前なので気にしないでください。
まず、以下のデータセットを見て下さい。
data RULE;
C1='赤';C2='青';COLOR='紫';output;
C1='青';C2='黄';COLOR='緑';output;
C1='黄';C2='赤';COLOR='橙';output;
run;
【データセット:RULE】
これは、2色の絵の具を混ぜた時に、できる色を示したパターン表です。
例えば1オブザベーション目は、赤と青を混ぜると紫ができるよということを示しています。
次にもう一つデータセットを見て下さい。
data Q1;
X='黄';Y='青';output;
X='赤';Y='赤';output;
X='黄';Y='赤';output;
X='赤';Y='青';output;
X='青';Y='青';output;
X='青';Y='黒';output;
run;
【データセット:Q1】
6オブザベーションあって、変数XとYそれぞれに色が入っています。
さて、今回の問題は、先に提示されたデータセット「RULE」の内容に基づいて
データセット[Q1]の6オブザベーション、全てに対して、混ぜたら何色になるかを
値として持たせなさいというものです。
ただし、以下の条件があります。
①同じ色を混ぜても、同じ色にしかなりません。つまり赤と赤を混ぜたら結果は赤です。
②RULEの中に存在しない組み合わせの色に対しては、結果が不明なので「×」といれます
③赤と青を混ぜるということと、青と赤を混ぜるということは同じとします。混ぜる際の色の指定順序に意味はありません。
さて、あなたなら、こういった処理をどのように解きますか?
ポイントは与えられたパターン表と色の順序が逆の場合の対応ですね。
順番が固定ならマージすりゃ終わりです。
なので、データセットRULEをいじって、C1とC2が逆の場合のデータも作って、6オブザベーションの
パターンが格納されたデータセットにしてからマージするのも、正解です。
でもなんかステップ数がかさむし、嫌だなと思って、以下のようにしました
data A1;
informat X Y COLOR;
if _N_=0 then set RULE;
if _N_=1 then do;
declare hash pallet(dataset:'RULE');
pallet.definekey('C1','C2');
pallet.definedata('COLOR');
pallet.definedone();
end;
set Q1;
if X=Y then COLOR=X;
else do;
C1=X;
C2=Y;
rc=pallet.find();
if rc^=0 then do;
C1=Y;
C2=X;
rc=pallet.find();
if rc^=0 then COLOR='×';
end;
end;
keep X Y COLOR;
run;
結果は
こんな感じで合ってます。
はい、つまりハッシュオブジェクト使いました。
このケースでは、使うべき処理でハッシュオブジェクト使えた気がします。
いや、1ステップだけど、こんな長いわけわからんコード書くぐらいなら細かくステップ分けるわ!
っていうご意見もごもっともです。
でも、SQLもそうだと思うのですが、最初、読み書きに抵抗があっても、
慣れればどうってことないっていうより、むしろ普通のデータセステップより読みやすいし、すらすら書けるってなります。
僕としては、多次元配列のARRAYで、深いループ書かれるより、ハッシュで書かれたコードの方が
行数があっても読みやすいと思っています。
で、実は今回は、今度のユーザー総会で発表する、ハッシュオブジェクトの前ふりでした。
上記コードの詳しい意味が知りたい方は是非、発表を聞いていただけると嬉しいです。
(もしからした発表時間のスケジュールが変わって、ハッシュはDAY1になるかも、、)
ただ、そのうち、このブログでもハッシュオブジェクトについて書いていきます。
0 件のコメント:
コメントを投稿