汎用的な入出力制御用マクロを一つ作っているだけで、効率よくプログラミングすることができます。
今回紹介するのは、簡単だけどいちいちコードを記述するのが面倒くさい、という悩みを解決するためのマクロです。
目次
1.サンプルデータ
サンプルとして、以下のデータを使用します。
data kojin_list;
infile datalines dlm="," dsd missover;
input
first_name :$20.
last_name :$20.
sex
age
;
datalines;
Kaori,Ito,2,22
Hideki,Tanaka,1,35
Taro,Yamada,1,30
Hiroki,Sato,1,25
Mizue,Ishii,2,54
Yuko,Koyama,2,30
Ichiro,Suzuki,1,.
Shinji,Suda,1,27
Reiko,Yamauchi,2,42
Mituru,Adachi,3,45
Kaori,Ito,2,44
Hiroki,Sato,2,25
Yuko,Koyama,2,30
Ichiro,Suzuki,1,.
;
run;
2.展開例
・WORK領域データを昇順ソートする
以下は、WORK領域にあるデータセットを昇順ソートするだけのシンプルな使い方です。
%sasdata(indata=kojin_list, outdata=kojin_list_ascending, key=first_name age);
引数keyで指定した変数で昇順ソートされました。
・WORK領域データを重複チェックして降順ソートする
以下のように、引数keyには降順ソート用のDESCENDINGオプションを指定することもできます。
%sasdata(indata=kojin_list, outdata=kojin_list_descending, key=descending first_name , dupchk=Y);
キー重複が見つかると、ログにエラーが出力されます。
以下のように、引数keyに指定した変数で降順ソートされています。
・WORK領域データから条件抽出する
以下は、WHEREデータセットオプションで条件抽出する例です。
%sasdata(indata=kojin_list(where=(sex=1)), outdata=kojin_list_where);
条件に合致したレコードのみ抽出されています。
・WORK領域データの変数名をリネームする
以下は、RENAMEデータセットオプションで変数名をリネームしながら読み込む例です。
%sasdata(indata=kojin_list(rename=(sex=sex2 age=age2)), outdata=kojin_list_rename);
変数名がsex→sex2、age→age2と変わりました。
・WORK領域データを縦結合する
以下のように、引数indataにデータセットを2つ指定すれば、単純な縦結合もできます。
もちろん、引数keyとdupchk=Yを指定すれば、重複チェックととソートも同時に行えます。
%sasdata(indata=kojin_list kojin_list, outdata=kojin_list2);
今回は引数indataに同じデータを2つ並べた例になります。
・重複チェックと昇順ソートをして永久データセットを出力
以下は、WORK領域のデータセットを重複チェックし、昇順ソートして永久データセットとして出力する例です。
%sasdata(path=C:\Blog\SAS\sasdata, indata=kojin_list, outdata=sd.kojin_list_ascending, key=first_name, dupchk=Y);
キー重複が見つかったら、ログにエラーが出力されます。
図ではわかりにくいのですが、以下は永久データセットをクリックして開いたもので、引数keyで指定した変数で昇順ソートされています。
・パスワードを付与して永久データセットを出力
%sasdata(path=C:\Blog\SAS\sasdata, indata=kojin_list, outdata=sd.kojin_list_password(pw=x9999));
パスワードを付与したデータセットを開こうとすると、パスワードを要求するウィンドウが表示されます。
・パスワードを解除して永久データセットを読み込む
%sasdata(path=C:\Blog\SAS\sasdata, indata=sd.kojin_list_password(pw=x9999), outdata=kojin_list);
これに関しては、パスワードを解除して読み込むだけなので、画像は省略しています。
3.参考プログラム
以下は、参考プログラムになります。
右上のコピーボタンを押せば、プログラム全体をコピーできます。
%macro sasdata(libname=sd, path=, indata=, outdata=, key=, dupchk=);
%put --------------------------------------------------;
%put sasdata; /*SASデータセットの入出力制御(永久データセット化、ソート、重複チェック、条件抽出、縦結合、リネーム、パスワード付与)*/
%put &=libname; /*参照名を指定(既定値=sd)*/
%put &=path; /*参照付けるフォルダパスを指定(省略可、永久データセットを扱う場合は指定必須)*/
%put &=indata; /*入力データセット名を指定(SASデータセットオプションの指定可、複数指定可)*/
%put &=outdata; /*出力データセット名を指定(SASデータセットオプションの指定可)*/
%put &=key; /*ソートして出力する場合は変数名を指定(省略可、複数指定可、降順ソートDESCENDING可)*/
%put &=dupchk; /*キーに対し重複チェックする場合はYを指定(省略可)*/
%put --------------------------------------------------;
/*ローカルマクロ変数*/
%local name qkey chkkey;
/*参照設定*/
libname &libname. "%superq(path)";
/*データの読込み*/
data _sasdata_temp;
set &indata.;
/*重複チェック*/
%if %length(&key.) > 0 and %upcase(&dupchk.)=Y %then %do;
%let chkkey=%sysfunc(tranwrd(&key., descending, %str()));
%let chkkey=%sysfunc(compbl(&chkkey.));
%let name = &sysindex;
retain _N_&name 1;
if _N_&name = 1 then do;
%let qkey = %sysfunc( tranwrd( %str("&chkkey.") , %str( ) , %str(",") ) );
declare hash h&name();
h&name..definekey(&qkey.);
h&name..definedone();
_N_&name = 0 ;
end;
drop _N_&name ;
if h&name..check() = 0 then put "ERROR:重複しています。" +1 (&chkkey.) (=);
else h&name..add();
%end;
run;
/*データの出力*/
%if %length(&key.) > 0 %then %do;
proc sort data=_sasdata_temp
out =&outdata.;
by &key.;
run;
%end;
%else %do;
data &outdata.;
set _sasdata_temp;
run;
%end;
/*参照名をクリア*/
libname &libname. clear;
/*不要データの削除*/
proc datasets lib=work noprint;
delete _sasdata_:;
quit;
%mend sasdata;