【SAS】変数の値が文字なのか数値なのか判定する


先日、数値しか入ってこないと聞いていた変数に、のっぴきならない事情で文字が入っていた外部データ(csv)を扱う機会がありました。
文字が入っていた場合は例外対応をしたいな~と思い、その際に調べたことをまとめます。

前提

  • SAS 9.4
  • SAS/STAT 15.1

compress関数を使う

前置き:そもそもcompress関数て何????

SAS compress関数
公式ドキュメントによると、

元の文字から指定した文字を削除した文字列を返します。

とあります。

構文

compress(source <,characters>, modifier )
第2引数と第3引数は省略可能です。

例えば、ABCDEからABCを削除したい場合は

X='ABCDE';
Y=compress(X,'ABC');
putlog(Y) // DE

となります。

ABCのみを保持して後は削除することもできます。

X='ABCDE';
Y=compress(X,'ABC',k); // 第3引数にkを指定すると「削除」ではなく「保持」される
putlog(Y) // ABC

本題:文字or数値判定

compress関数が、元の文字から指定した文字を削除(あるいは保持)することを利用します。

例えば、
「0123abc456」という数値と文字が混ざっているものから、数値のみ削除する場合、

X='0123abc456';
Y=compress(X,'','kf'); //アンダースコア、英文字を保持 ※ [k]は保持、[f]はアンダースコア文字および英文字を表す
putlog(Y); // abc

X='0123456';
Y=compress(X,'','kf');
putlog(Y); // '' アンダースコア、英文字を保持(それ以外は削除)されるので空白''が返ってくる

使用例

以下のようなデータがあった場合

hogeが数値の場合と文字の場合で、格納変数を分ける。
※hogeは文字型で定義されているものとします。

// 数値と文字が混じったデータ
data A1;
    input hoge$;
    cards;
    0
    1
    2
    3
    4
    a
    b
    c
    ;
run;

data A2;
    attrib num length=8;
    attrib char length=$20;
    set A1;
    // hogeに文字が含まれていればchar、含まれていなければnumに格納する
    if compress(hoge,'','kf') ^= '' then character=hoge; else number=hoge;

    keep num cha;
run;

実行結果

補足

compress関数の第2引数と第3引数には変数、式、固定値を指定することができます。詳細は公式ドキュメントをご参照いただければと思います。