SASマクロ マクロの作成

【SAS】データセット内の指定した変数の変数値をマクロ変数化する(SYMPUT、SUPERQ)

1.サンプルデータ

サンプルとして、以下のSASデータセット「list.sas7bdat」があるとします。

data list;
	infile datalines dlm="," dsd missover;
	input
		first_name	:$20.
		last_name	:$20.
		sex		:8.
		age		:8.
	;
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
;
run;

このSASデータセットの変数値をマクロ変数化していきます。
list

 

2.展開例

以下は、展開した例になります。

%mk_macvar(indata=list, var=first_name last_name sex age, num=nword);

展開すると、以下のようなログが出力され、マクロ変数が作成されたことを確認できます。
mk_macvar_log
 

・生成されたグローバルマクロ変数
ログを見てわかるように、以下のグローバルマクロ変数が生成されており、データセットのレコード数や変数値が格納されています。

nword
first_name_1-first_name_10
last_name_1-last_name_10
sex_1-sex_10
age_1-age_10

 
・マクロ変数化した変数値を使用する
%DOステートメントを使用すれば、一度生成したマクロ変数を好きなように展開できます。

%macro mk_list;

	data list2;
		length
			first_name
			last_name
			$20.
		;

		%do i=1 %to &nword.;
			first_name="&&first_name_&i..";
			last_name="&&last_name_&i..";
			sex=&&sex_&i..;
			age=&&age_&i..;
			output;
		%end;

	run;

%mend mk_list;
%mk_list;

 
マクロ変数化した変数値を展開して、元のデータセットを再現してみました。
mk_macvar_list2
 

3.参考プログラム

以下は、参考プログラムになります。
右上のコピーボタンを押せば、プログラム全体をコピーできます。

%macro mk_macvar(indata=, var=, num=nword);
%put --------------------------------------------------;
%put mk_macvar;
%put データセットの指定した変数の変数値をマクロ変数化する;
%put &=indata;	/*データセット名を指定(データセットオプションの指定可)*/
%put &=var;	/*マクロ変数化対象の変数名を指定する(スペース区切りで複数指定可)*/
%put &=num;	/*読込データセットのレコード数を格納するマクロ変数名を指定する(デフォルト:nword)*/
%put --------------------------------------------------;

	%if %symexist(&num.) %then %put WARNING:既存のマクロ変数&num.を更新します;

	/*グローバル化*/
	%global &num.;

	/*データの読込*/
	data _mk_macvar_temp;
		set &indata.;
	run;

	/*マクロ変数化*/
	data _null_;
		set _mk_macvar_temp;

		call symputx("&num.", put(_n_,best.));
		%let __i=1;
		%do %while(%scan(&var., &__i.,, s) ne);
			call symputx(cats("%scan(&var., &__i.,, s)_",put(_n_, best.)), %scan(&var., &__i.,, s) , "G");
			%let __i=%eval(&__i.+1);
		%end;
	run;

	%put;
	%put ***** マクロ変数化のチェック開始 *****;
	%put;

	%put &num.=%superq(&num.);
	%put;

	%let check=3;
	%put ***** 最初と最後の&check.行のみチェック *****;
	%put;

	%let __i=1;
        %do %while(%scan(&var.,&__i,,s) ne);
		%do __k=1 %to %sysfunc(min(&check., %superq(&num.)));
			%put %scan(&var.,&__i.,,s)_&__k.=%superq(%scan(&var.,&__i.,,s)_&__k.);
		%end;
		%do __k=%sysfunc(min(&check., %superq(&num.))) %to 1 %by -1;
			%put %scan(&var.,&__i.,,s)_%eval(%superq(&num.)-&__k.+1)=%superq(%scan(&var.,&__i.,,s)_%eval(%superq(&num.)-&__k.+1));
		%end;

		%put;

		%let __i=%eval(&__i.+1);
	%end;

	%put;
	%put ***** マクロ変数化のチェック終了 *****;
	%put;

%mend mk_macvar;