計算前にnullチェックをしたい

スポンサーリンク

SAS独特の書き方があったのでメモ。

スポンサーリンク

概要

数値計算をする際にnull値があるとうれしくないNOTEが出てしまいます。成果物としてよろしくないので内部で処理をする方法をいくつか記録しておきます。

データ準備

data days;
  informat start_date end_date $10.;
  input start_date $ end_date $;
cards;
2021-08-01 2021-08-11
2021-08-01 2021-08-21
.          2021-08-31
2021-08-01 .
.          .
;
run;

data days_1;
  set days;
  length start_day end_day 8.;
  format start_day end_day yymmdd10.;
  
  start_day = input(start_date, yymmdd10.);
  end_day   = input(end_date,   yymmdd10.);
run;

データを作成して計算対象となる変数を数値に変換しておきます。


うれしくないNOTEが出るパターン

data days_2;
  set days_1;
  length day_delta 8.;

  day_delta = end_day - start_day;
run;

結果だけ見ると問題ないように見えます。

しかしながらログにこのNOTEが出てしまうのはよろしくないので対応しないといけません。


直感的にわかるパターン(変数を直接評価)

data days_3;
  set days_1;
  length day_delta 8.;

  if start_day ^= . and end_day ^= . then do;
    day_delta = end_day - start_day;
  end;
  else day_delta = 999;
run;

計算する変数がnullでない場合も処理がされていることを示すため、便宜的に999を入れています。
以降の例ですべて同じ結果となります。


missing関数

missing関数は、引数が欠損値を含むかどうかの結果を表す数値を返します。
欠損値が含まれていない場合→0を返します。
欠損値が含まれている場合→1を返します。
引数は1つだけ指定できます。

data days_4;
  set days_1;
  length day_delta 8.;
  
  if missing(start_day) = 0 and missing(end_day) = 0 then do;
    day_delta = end_day - start_day;
  end;
  else day_delta = 999;
run;

cmiss関数

cmiss関数は欠損引数の数を数えます。
引数は複数指定できます。

data days_5;
  set days_1;
  length day_delta 8.;
  
  if cmiss(start_day, end_day) = 0 then do;
    day_delta = end_day - start_day;
  end;
  else day_delta = 999;
run;

cmissが一番すっきりしたコードに見えます。

コメント