SASマクロ データの入出力

【SAS】SASデータセットの入出力制御(永久データセット化、ソート、重複チェック、パスワード)

汎用的な入出力制御用マクロを一つ作っているだけで、効率よくプログラミングすることができます。
今回紹介するのは、簡単だけどいちいちコードを記述するのが面倒くさい、という悩みを解決するためのマクロです。

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;

kojin_list_new
 

2.展開例

・WORK領域データを昇順ソートする

以下は、WORK領域にあるデータセットを昇順ソートするだけのシンプルな使い方です。

%sasdata(indata=kojin_list, outdata=kojin_list_ascending, key=first_name age);

 
引数keyで指定した変数で昇順ソートされました。
kojin_list_ascending
 

・WORK領域データを重複チェックして降順ソートする

以下のように、引数keyには降順ソート用のDESCENDINGオプションを指定することもできます。

%sasdata(indata=kojin_list, outdata=kojin_list_descending, key=descending first_name , dupchk=Y);

 
キー重複が見つかると、ログにエラーが出力されます。
kojin_list_dupchk_descending_log
 
以下のように、引数keyに指定した変数で降順ソートされています。
kojin_list_dupchk_descending_data
 

・WORK領域データから条件抽出する

以下は、WHEREデータセットオプションで条件抽出する例です。

%sasdata(indata=kojin_list(where=(sex=1)), outdata=kojin_list_where);

 
条件に合致したレコードのみ抽出されています。
kojin_list_where
 

・WORK領域データの変数名をリネームする

以下は、RENAMEデータセットオプションで変数名をリネームしながら読み込む例です。

%sasdata(indata=kojin_list(rename=(sex=sex2 age=age2)), outdata=kojin_list_rename);

 
変数名がsex→sex2、age→age2と変わりました。
kojin_list_rename
 

・WORK領域データを縦結合する

以下のように、引数indataにデータセットを2つ指定すれば、単純な縦結合もできます。
もちろん、引数keyとdupchk=Yを指定すれば、重複チェックととソートも同時に行えます。

%sasdata(indata=kojin_list kojin_list, outdata=kojin_list2);

 
今回は引数indataに同じデータを2つ並べた例になります。
kojin_list2
 

・重複チェックと昇順ソートをして永久データセットを出力

以下は、WORK領域のデータセットを重複チェックし、昇順ソートして永久データセットとして出力する例です。

%sasdata(path=C:\Blog\SAS\sasdata, indata=kojin_list, outdata=sd.kojin_list_ascending, key=first_name, dupchk=Y);

 
キー重複が見つかったら、ログにエラーが出力されます。
kojin_list_lib_dupchk_ascending_log
 
図ではわかりにくいのですが、以下は永久データセットをクリックして開いたもので、引数keyで指定した変数で昇順ソートされています。
kojin_list_lib_dupchk_ascending_data
 

・パスワードを付与して永久データセットを出力

%sasdata(path=C:\Blog\SAS\sasdata, indata=kojin_list, outdata=sd.kojin_list_password(pw=x9999));

パスワードを付与したデータセットを開こうとすると、パスワードを要求するウィンドウが表示されます。
kojin_list_password
 

・パスワードを解除して永久データセットを読み込む

%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;