SAS

SASで使える!実用データクリーニングテクニック

SASに限らずデータクリーニングや前処理はデータ分析の分野では必須の工程であり、おそらく今後も人の手で実施しなくてはならない分野です。

個人的には機械学習のライブラリとかよりもはるかに習得優先度が高いと思います。

SASを使ったデータクリーニング方法って案外共有されていない印象だったのでメモしておきます。

データクリーニングテクニックとはいっても、どのデータがおかしいかを検出するのが全てですので、データクリーニングは想定外データの検出する工程とも言えます
検出できればあとは該当データを修正、削除をすればよいわけです。

想定外のコード値の入力を検出する

性別や体重区分などのカテゴリを数値として読み替えてフォーマットを適用するとき、想定外のコード値が入力されていないかどうかを調べます。whereステートメントを使う方法とselect文を使う方法は絶対おぼえておいたほうがいいです。

Freqプロシジャで集計する

すぐに思いつく方法はFreqプロシジャで集計する方法です。例えば性別を以下のように集計すれば、想定外のコード値が存在する場合集計されるので、想定外のコードがあるかどうかがわかります。

proc freq data=ds1 noprint; 
tables gender / out=check missing; 
run;

whereステートメントで抽出する

想定外のコードが含まれるデータを抽出する場合はwhereステートメントで抽出します。検出されたデータに対して別途処理を実施できるのでこっちのほうが便利かな。
whereステートメントはprxmatchなどの正規表現関数が使えるので、応用範囲は広いです。

正規表現の実用例は以下の記事で紹介しています。

SASで正規表現を利用する私はデータチェックの時に正規表現を利用することがありますが、同僚はあまり使っていないらしく、後輩は正規表現自体を知らないとのことだったの...

set ds1; 

/*コード値:Male=1, Female=2*/ 
where gender not in(.,1,2); 
run;

規定外データにフォーマットを適用する

フォーマットに既定のコード値以外の表示値を定義するのも手だと思います。proc formatでユーザー定義フォーマットを作成する際に、otherキーワードを使用することで規定のコード値以外の値にも任意のフォーマットを当てることができます。

これはデータセットを目視確認したいときに誤りを発見しやすくなるメリットがあります

proc format; 
/*不正なコード値にもフォーマットを適用する*/ 

value sexf 1="M" 
           2="F" 
           .="Null" 
           other="コード値が間違ってます"; 
run; 

data test; 
format gender sexf.; 
input gender; 
cards; 
1 
1 
2 
1 
2 
2 
2 
. 
1 
3 
8 
; 
run;

データセットを表示すると以下のようになります。ぱっと見どこのデータがおかしいのかすぐわかりますね。

Obsgender
1M
2M
3F
4M
5F
6F
7F
8Null
9M
10コード値が間違ってます
11コード値が間違ってます

select文を利用する

select文のotherwiseステートメントを利用して規定外の入力があった場合の処理を追加します。if文でも同じことができますが、select文は規定していないコードがあるとエラーになりますので
異常に気付きやすいです。

一番汎用性が高いのはputステートメントを使ってログに警告文を表示する方法です。ERRORの文字列を追加しておくとログの文字列の色が変わりますのですぐにわかります。

コードを実行するとログに以下のような警告が表示されます。

ERROR: 規定外のコード値です USUBJID=SA-010

ERROR: 規定外のコード値です USUBJID=SA-011

外れ値を検出する

極端に大きな値あるいは極端に小さな値を外れ値(outlier)と呼びます。外れ値は要約統計量の算出やモデルを構築する際に悪影響を及ぼします。臨床試験では外れ値を除外することは普通ないと思います。というのも数学的に外れ値を定義することはできてもそれが妥当なのかどうかは証明することは難しいからです。例えば臨床検査値はかなり個人差がありますから、一見異常値にみえても実は正しい値の可能性もあります。

安易に外れ値を除外すると恣意的なデータ操作を疑われかねないので、計画通りにデータが取得できなかったとか、プロトコールで定義されているなどの明確な理由ががない限り行わないほうが無難だと思います。

では臨床試験において外れ値は気にする必要はないかというとそうでもないです。データの入力ミスや単位間違いなどのデータ作成時もミスの可能性もあるので、外れ値が本当に正しいかどうかは確認して損はないと思います。特に単位間違いは本当に気を付けないとひどい目にあいます!気を付けましょう。

SASで実施する方法としては、

  • 散布図や箱ひげ図を作図して目視で外れ値の存在の有無を確認する。
  • meanプロシジャやunivarateプロシジャで最大値、最小値を求める。
  • 平均値から3σ以上離れたデータを検出する
  • IQR(四分位範囲)に基づいて外れ値を検出する

あたりかと思います。

個人的には散布図や箱ひげ図を作るほうが直感的で一番簡単かなと思います。 sgplotで直ぐに描けますし。

平均値から3σ以上離れたデータを検出するというのは、3σ以上離れたデータは正規分布を仮定した時に発生する確率が0.27%以下であることが根拠となっています。
ただしデータの分布が正規分布に従っている必要があるので、分布形状を確認するためにやはり作図したほうが良いと思います。

データの可視化は分布の形状の判断だけでなく外れ値の確認も直感的に行うことができる実用性の高い技術です。

以下のコードはデータセット内のすべての数値変数から箱ひげ図を作成します。箱ひげ図であれば外れ値がマーカーとして表示されるので、外れ値の有無と分布形状を同時に確認できます。

%macro box(ds=, var=,); 
   proc sgplot data=&ds.; 
   vbox &var.; 
   run; 
%mend; 

*データセット内の変数情報を取得; 
proc contents data=sashelp.iris out=cont noprint;
run; 

*数値変数のみ箱ひげ図を作図する; 
data _null_;
set cont; 
if type=1 then call execute("%box(ds="||libname||"."||memname||", var="||name||");"); 
run;