目次
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;
2.展開例
・全欠損(欠損率100%)のみ出力
以下は、全レコードが欠損の変数のみ出力する場合の展開例です。
%check_missing(indata=kojin_list, outdata=missing_list);
以下のように、NMISSRATE=1、すなわち、欠損率100%の変数のみログに出力されました。
以下は引数outdataで指定したデータセットの中身になります。
・欠損率を指定して(下げて)出力
以下の例では、引数rate=0、すなわち、全変数を出力対象とする展開例です。
rate=0.8とすれば、8割以上が欠損している変数のみに絞れます。
%check_missing(indata=kojin_list, rate=0, outdata=missing_list);
今度は全変数の欠損率がログに出力されました。
もちろん、データセットの中身も全変数が揃っています。
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;