2026年5月4日月曜日

複数の文字変数の非欠損の数を数える話

SASで複数の変数の欠損の数を数えるにはcmiss関数があります。cmiss関数は便利な関数で、1obsの中で文字だろうが数字だろうが指定した変数の中の欠損の数を数えてくれます。非欠損の変数の数を数える際は、数字変数ならn関数というこれまた便利な関数があります。

一方文字変数の中で非欠損の数を数えたいときはいつも難儀していました。良い感じの関数が多分sasにはないです。あったらすみません。しょうがないので配列で数えたいうのが今回の記事です。文字変数と銘打っていますが欠測かどうかをmissing関数で調べているので、多分文字でも数字でも非欠損の数を出せると思います。文字でしか試してないのでerrorになるかもしれませんが。

対象の変数を指定している配列の部分をマクロ変数化すればいい感じのマクロになるんじゃないでしょうか?可変なのがその部分だけ、強いて言えばそこと結果を格納する変数名の部分だけなので。



data hoge ;
    a = "a" ; b = "" ; c = "" ; output ;
    a = "a" ; b = "b" ; c = "" ; output ;
run ;

data _null_ ;
    set hoge ;

    res = 0 ;
    array vars  a b c;
    do over vars ;
        if missing(vars) = 0 then res = res + 1;
    end;

    putlog res = ;

run;

/*>>>>>---------- 以下実行log ----------<<<<<*/

3956
3957  data _null_ ;
3958      set hoge ;
3959
3960      res = 0 ;
3961      array vars  a b c;
3962      do over vars ;
3963          if missing(vars) = 0 then res = res + 1;
3964      end;
3965
3966      putlog res = ;
3967
3968  run;

res=1
res=2

2026年3月1日日曜日

フォルダに格納したsasファイルを全部読み込む話

 先日紹介したsas公式のgithubの中に、指定したフォルダ内の全てのsasプログラムを読み込むマクロが含まれている。ある程度指定した順番に読み込んだりと高機能なものだ。

その辺の微調整が出来ないもっと単純な読み込みプログラムを私も持っているので、せっかくということで記事にする。以下の1行で指定したフォルダ、今回はhoge直下の.sasファイルを全部読み込んでいる。読み込む順番が調整できなかったりなどできないことが多いが、まあ気を付けていれば私には今の所コレで十分ではある

%include "%nrbquote(hoge\*.sas)";

2026年2月1日日曜日

0件のデータセット作るときに初期化が云々のメッセージって出ないように出来ませんでしたっけ?

変数ラベルや長さなどの変数情報だけを確定させるために0obsのデータセットを作ることがあるのですが、昔はstopステートメントを仕込めば初期化されていませんのメッセージを出さないように出来……ましたよね?0件のデータセット作るときのログに初期化されていませんのメッセージ出るとちょっと嫌だったので……

どうもちょっと前からstopを仕込んでもログに初期化されて~のメッセージが出てる気がするんですよね…そもそも昔からこのメッセージは出ていたのか?手癖で処理していたのでちゃんと覚えてない自分が恨めしい

以下の様に変数aの定義だけ持たせた0件のデータを作成すると、値が無いのでメッセージが出ます

17   data piyo ;

18   attrib  a length = $10 ;

19   run ;

NOTE: 変数aは初期化されていません。  <- これ

NOTE: データセットWORK.PIYOは1オブザベーション、1変数です。

NOTE: DATA ステートメント処理(合計処理時間):

      処理時間           0.03 秒

      CPU時間            0.01 秒


ここに以下の様にデータステップ内にstopステートメントを仕込むと、このメッセージを出なく出来ていた……ような……あいまいな記憶の記事ですみません。気のせいですかね

21   data piyo ;

22   attrib  a length = $10 ;

23   stop ;

24   run ;

NOTE: 変数aは初期化されていません。 <- これが昔は出なかったような…

NOTE: データセットWORK.PIYOは0オブザベーション、1変数です。

NOTE: DATA ステートメント処理(合計処理時間):

      処理時間           0.06 秒

      CPU時間            0.01 秒


2026年1月19日月曜日

データセットがキーとなる変数で重複が無いかを確認する

 キーとなる変数でデータセットが一意に定まるかを確認する時はproc sortを使っています。nouniquekeyオプションを使えば、重複してるレコードをだけをデータセットとして作れるので便利ですね。

仮にデータセットhogeが以下の様にあったとして、変数aの値が1obsと2obsで1で重複しています

後は以下の通り重複するobsをKEY_NO_UNIQUEデータセットに格納して、このデータセットにレコードがあればログにerrorを出す、とすれば重複があるかどうかはログを見るだけでokです。詳しい重複の内容はデータセットを見てください。

proc sort data = hoge out = KEY_NO_UNIQUE nouniquekey  ;

  by a  ;

run ;

data _null_ ;

    if 0 then set KEY_NO_UNIQUE nobs = _nobs ;

    if _nobs ^= 0 then putlog "E" "RROR NoUnique: Check KEY_NO_UNIQUE dataset" ;

    stop ;

run ;