問題です。次のプログラムを実行すると、どんなデータセットができるでしょうか?
data A;
X=5=5;
run;
最近、こういう系の話ばっかりしていて、飽きているかもしれませんが。
エラーになってデータセットができない or X=5でデータセットができると考えた方は不正解です。
正解は
X=1でデータセットができるでした。
これは実は
X=(条件式);の形で、条件式の中が真である場合は、1、偽である場合は0を返します。
つまり先程のコードはX=(5=5);ということで、5と5は等しいので真でありX=1です。
要するに、これを利用することで簡単に0,1のフラグ変数を作れて、条件で集計する場合などに
役立ちますという話です。
今、以下のようなデータセットがあったとします。
data Q1;
X=2;Y=1;output;
X=3;Y=2;output;
X=5;Y=2;output;
X=4;Y=8;output;
run;
ここで、X>Y and X^=2の条件で0,1変数を作りたいなと思ったら
data A1;
set Q1;
FLAG=X>Y and X^=2;
run;
で、詰みなんです。簡単です。
ちなみに恥ずかしい話なんですが、僕はずっと上記のコードで済むところを
以下のように
data A2;
set Q1;
FLAG=ifn(X>Y and X^=2,1,0);
run;
ifn関数を使っていました。
条件によって戻り値を加工したい場合はifn(戻り値が文字型ならifc)ですが
0,1の戻り値なら普通に抽出式書くだけなんですね。
ちなみにSQLプロシジャにおいても、ほぼ同じ話があって、そちらの詳細は
ブログ「SAS忘備録」の「SQLプロシジャでフラグ変数を簡単に作成。 」という記事に書かれていて目から鱗ものですよ。
http://sas-boubi.blogspot.jp/2013/12/sql.html
ちなみSQLプロシジャでIFN IFC関数を利用して、0,1のフラグ変数ではなく、
条件式によって戻り値を変えるという方法については、本ブログの以下の記事で僕も書いています。
「SQLのCASE式がどうしても苦手な場合、IFC、IFN関数で代用してみる 」
http://sas-tumesas.blogspot.jp/2013/11/sqlcaseifcifn.html
SQLのCASE式がどうしても苦手な場合、IFC、IFN関数で代用してみる
SQLにIF文はないのかは、よく尋ねられる話です。MySQLなど特定の製品の独自関数として定義されている場合を除いて、基本的にSQLにIFはありません。
SQLでの条件分岐はCASE式を使うのですが、普段書いているSASのIFステートメントと少し違うので、なかなか書き方がぱっとでてこず、調べたりしてしまうことが多い方もいると思います。
条件分岐が面倒だからSQLは使わないという方もいたりするので、邪道かもしれませんが、SASでのSQLの使用を普及させたい僕としては、どうしてもCASE文が嫌いならとりあえずIFC,IFN関数を使ってみればと提案しています。
戻り値が数字の場合はIFN、文字の場合はIFC関数になります。
この関数はEXCELのIF関数と同じで
IFN(条件式,真の場合の戻り値,偽の場合の戻り値)といった感じで使います。
まず通常のデータステップで説明します。
以下のデータセットがあったとします。
data Q1;
X=1;Y='い';output;
X=2;Y='ろ';output;
X=3;Y='は';output;
run;
data A1;
set Q1;
_X=IFN(X=1,X*10,X*20);
_Y=IFC(Y='い','A','B');
run;
を実行すると
こうなります。
関数を入れ子にすることで、階層的な条件分岐を表現できます。
data A2;
set Q1;
_X=IFN(X=1,X*10,IFN(X=2,X*20,999));
_Y=IFC(Y='い','A',IFC(Y='ろ','B','Z'));
run;
を実行すると
となります。
これをSQLのCASE式でかくなら
proc sql noprint;
create table A3 as
select X,Y
,case X
when 1 then X*10
when 2 then X*20
else 999
end as X_
,case Y
when 'い' then 'A'
when 'ろ' then 'B'
else 'Z'
end as Y_ length=200
from Q1;
quit;
となります。改行の仕方によりますが、やはりぱっと見、ボリュームが、もさっとしがちに感じてしまします。
そこで、IFC IFN関数を使用してみます。
proc sql noprint;
create table A4 as
select X,Y
,IFN(X=1,X*10,IFN(X=2,X*20,999)) as _X
,IFC(Y='い','A',IFC(Y='ろ','B','Z')) as _Y
from Q1;
quit;
SQLでの条件分岐はCASE式を使うのですが、普段書いているSASのIFステートメントと少し違うので、なかなか書き方がぱっとでてこず、調べたりしてしまうことが多い方もいると思います。
条件分岐が面倒だからSQLは使わないという方もいたりするので、邪道かもしれませんが、SASでのSQLの使用を普及させたい僕としては、どうしてもCASE文が嫌いならとりあえずIFC,IFN関数を使ってみればと提案しています。
戻り値が数字の場合はIFN、文字の場合はIFC関数になります。
この関数はEXCELのIF関数と同じで
IFN(条件式,真の場合の戻り値,偽の場合の戻り値)といった感じで使います。
まず通常のデータステップで説明します。
以下のデータセットがあったとします。
data Q1;
X=1;Y='い';output;
X=2;Y='ろ';output;
X=3;Y='は';output;
run;
data A1;
set Q1;
_X=IFN(X=1,X*10,X*20);
_Y=IFC(Y='い','A','B');
run;
を実行すると
こうなります。
関数を入れ子にすることで、階層的な条件分岐を表現できます。
data A2;
set Q1;
_X=IFN(X=1,X*10,IFN(X=2,X*20,999));
_Y=IFC(Y='い','A',IFC(Y='ろ','B','Z'));
run;
を実行すると
となります。
これをSQLのCASE式でかくなら
proc sql noprint;
create table A3 as
select X,Y
,case X
when 1 then X*10
when 2 then X*20
else 999
end as X_
,case Y
when 'い' then 'A'
when 'ろ' then 'B'
else 'Z'
end as Y_ length=200
from Q1;
quit;
となります。改行の仕方によりますが、やはりぱっと見、ボリュームが、もさっとしがちに感じてしまします。
そこで、IFC IFN関数を使用してみます。
proc sql noprint;
create table A4 as
select X,Y
,IFN(X=1,X*10,IFN(X=2,X*20,999)) as _X
,IFC(Y='い','A',IFC(Y='ろ','B','Z')) as _Y
from Q1;
quit;
こざっぱりします。ただ条件分岐が多くて入れ子にすると深すぎるなら、
CASE式の方が見通しやすいと思います。
まあ好みの問題ですが、無理してでもCASE式の書き方に慣れた方が、他のシステムで
SQL書くときにも使えるので、いいとは思います。
登録:
投稿 (Atom)





