全ての値が欠損値の数値変数と文字変数を削除する

[OS]ALL
[リリース] 6.12, 8.1, 8.2
[キーワード] MISSING, MISSING VALUE, VARIABLE

[質問]

数値変数や文字変数の全ての値が欠損値の場合、それらの変数を削除する方法はありますか?

[回答]

プロシジャやDATAステップのオプションなどでは、そのような機能はサポートされていません。次のマクロで、全ての値が欠損値の変数を削除できます。

                                  /* サンプルデータセットの作成 */
DATA sample;
  INPUT num1-num3 (char1-char4) ($);
CARDS;
1 . .  A . . .
. . .  . . . B
3 . .  C . . .
;
RUN;

%MACRO rm_miss(ds,out_ds);

%** ds: 入力データセット     ***; 
%** out_ds: 出力データセット ***; 

                                            /* 文字変数名を取得 */
  PROC CONTENTS DATA=&ds OUT=_out1(WHERE=(type=2)) NOPRINT;
  RUN;

  DATA _null_;
    SET _out1;
    CALL SYMPUT('n_c',LEFT(_n_));
    CALL SYMPUT('c_var' || LEFT (_n_),name);
  RUN;
                                            /* 数値変数名を取得 */
  PROC CONTENTS DATA=&ds OUT=_out2(WHERE=(type=1)) NOPRINT;
  RUN;

  DATA _null_;
    SET _out2;
    CALL SYMPUT('n_n',LEFT(_n_));
    CALL SYMPUT('n_var' || LEFT (_n_),name);
  RUN;

                      /* 各文字変数の欠損値以外の件数をカウント */
  PROC SQL NOPRINT;
    %DO i = 1 %TO &n_c;
      SELECT COUNT(&&c_var&i) INTO:c&i FROM &ds 
      WHERE &&c_var&i NOT = ' ';
    %END;
  QUIT;

                      /* 各数値変数の欠損値以外の件数をカウント */
  PROC SQL NOPRINT;
    %DO i = 1 %TO &n_n;
      SELECT COUNT(&&n_var&i) INTO:n&i FROM &ds 
      WHERE &&n_var&i NOT = .;
    %END;
  QUIT;

                                /* 全ての値が欠損値の変数を削除 */
  DATA &out_ds;
    SET &ds;
    %DO i=1 %TO &n_c;
      %IF &&c&i = 0 %THEN %DO;
        DROP   &&c_var&i;
      %END;
    %END;
    %DO i=1 %TO &n_n;
      %IF &&n&i = 0 %THEN %DO;
        DROP   &&n_var&i;
      %END;
    %END;
  RUN;

  PROC DATASETS LIB=work NOLIST;
    DELETE _out1 _out2;
  RUN;
  QUIT;
%MEND rm_miss;

%rm_miss(sample,sample2);    /* マクロの実行 */