SASマクロ チェック作業

【SAS】変数の欠損率(欠測データの割合)をチェックする(MISSING、合計ステートメント)

check_missing_0_data

1.サンプルデータ

以下のサンプルデータの欠損率を調べてみます。

data kojin_list;
	infile datalines dlm="," dsd missover;
	input
		first_name	:$20.
		last_name	:$20.
		sex
		age
	;
	label
		first_name	="名"
		last_name	="姓"
		sex			="性別"
		age=		"年齢"
	;
datalines;
Kaori,Ito,,22
,Tanaka,,35
Taro,Yamada,,30
,Sato,,25
Mizue,Ishii,,54
Yuko,Koyama,,30
Ichiro,Suzuki,,
,Suda,,27
Reiko,Yamauchi,,42
,Adachi,,45
,Ito,,44
,Sato,,25
,Koyama,,30
,Suzuki,,
;
run;

kojin_list
 

2.展開例

・全欠損(欠損率100%)のみ出力

以下は、全レコードが欠損の変数のみ出力する場合の展開例です。

%check_missing(indata=kojin_list, outdata=missing_list);

以下のように、NMISSRATE=1、すなわち、欠損率100%の変数のみログに出力されました。
check_missing_allmiss_log
 
以下は引数outdataで指定したデータセットの中身になります。
check_missing_allmiss_data
 

・欠損率を指定して(下げて)出力

以下の例では、引数rate=0、すなわち、全変数を出力対象とする展開例です。
rate=0.8とすれば、8割以上が欠損している変数のみに絞れます。

%check_missing(indata=kojin_list, rate=0, outdata=missing_list);

今度は全変数の欠損率がログに出力されました。
check_missing_0_log
 
もちろん、データセットの中身も全変数が揃っています。
check_missing_0_data
 

3.参考プログラム

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

%macro check_missing(indata=, var=, rate=1, outdata=);
%put --------------------------------------------------;
%put check_missing;	/*変数の欠損率(欠測データの割合)をチェックする*/
%put &=indata;		/*チェック対象をデータセットを指定(データセットオプションの指定可)*/
%put &=var;			/*チェック対象変数を指定(省略した場合は全変数対象)*/
%put &=rate;		/*出力対象の欠損率下限を指定(既定値=1、全欠損の変数のみ)*/
%put &=outdata;		/*欠損率データの出力(省略した場合はログのみ出力する)*/
%put --------------------------------------------------;

	/*データの読み込み*/
	data _check_missing_data;
		%if %length(&var.) > 0 %then %do;
			format &var.;
			keep &var.;
		%end;
		set %superq(indata);
	run;

	%if &sysnobs.= 0 %then %do;
		%put WARNING:入力データセットは空です。;
		%put WARNING:%nrstr(%check_missing)を終了します。;
		%goto exit;
	%end;

	/*変数情報の取得*/
	proc contents data=_check_missing_data out=_check_missing_cont(keep=VARNUM NOBS NAME LABEL TYPE) noprint;
	run;
	proc sort data=_check_missing_cont;
		by varnum;
	run;
	data _null_;
		set _check_missing_cont;
		call symputx("varnum", _n_);
		call symputx(cats("var", _n_), name);
	run;

	/*集計*/
	data _check_missing_sum;
		keep _nmiss_:;
		set _check_missing_data end=eof;

		%do __i=1 %to &varnum.;
			if missing(&&var&__i..) then _nmiss_&__i. + 1;
		%end;

		if eof;
	run;

	/*行列変換*/
	proc transpose 	data=_check_missing_sum
					out =_check_missing_sum_tran(keep=col1 rename=(col1=NMISS));
		var _nmiss_1 - _nmiss_&varnum.;
	run;
	data _check_missing_sum_tran;
		set _check_missing_sum_tran;
		varnum = _n_;
	run;

	/*変数情報のマージ*/
	data 
		%if %length(%superq(outdata)) > 0 %then %do;
			%superq(outdata)
		%end;
		%else %do;
			_null_
		%end;
		;
		format
			VARNUM
			NAME
			LABEL
			TYPE
			NOBS
			N
			NMISS
			NRATE
			NMISSRATE
		;

		merge
			_check_missing_cont(in=in1)
			_check_missing_sum_tran(in=in2)
		;
		by varnum;
		if not(in1 and in2) then put "ERROR:ここでのアンマッチはあり得ない!"(varnum)(=);
	
		N		 = SUM(NOBS, -NMISS);
		NRATE	 = N / NOBS;
		NMISSRATE= NMISS / NOBS;

		/*引数rateで指定した欠損率以上の変数のみに絞る*/
		if NMISSRATE >= &rate.;
		put "WARNING:欠損率:" (NAME NMISSRATE)(=);
	run;

	/*%GOTO先*/
	%exit:

	/*不要データの削除*/
	proc datasets lib=work noprint;
		delete _check_missing_:;
	quit;

%mend check_missing;