【SAS】Enterprise Guideを止めるコマンドは存在しない!
該当する人は多くないかもしれませんが、SAS Enterprise Guide(以下EG)での作業が定常化してきて、EGのスケジュールを用いてWindowsのタスクスケジューラに登録してバッチ化しています。(残念ながら、Base SASは現環境にありません)
そうすると、データが存在するかどうかを確認して、存在しなかったらEGを止める必要が出てきました。
EGはコマンドでは止まりません
結論から言うと、EGはコマンドでは止まりません。
同じようなことを考える人はいるようで、"SAS Enterprise Guide vs. Batch"という、タイトルを見ただけで軽く笑いがこみ上げてくる論文を見てみたところ
- OPTIONS SYNTAXCHECK
- ENDSAS
- OPTIONS ERRORABEND
- ABORT statement
- %ABORT statement
- 自動マクロ変数 &SYSERROR
とか、全部試してみたけど、プロセスフローの上流にあるプログラムは止まっても、下流のプログラムは止まらない。
下手すると、下流でサーバに再接続して実行するから有害、とのことでした。
【SAS】キーが複数存在するテーブルで重複レコードを抽出する
重複レコードの数を数える
キーが複数あるようなテーブルで、重複しているレコードを取り出したいことがある。
そんなときは、まず重複するレコード数を数える。
たとえば、ID1とID2の2つを指定することでレコードが一意になるテーブルで、ID1とID2のセットで重複がいくつあるか数える場合は次のSQLが使える。
PROC SQL; CREATE TABLE DUPLICATION_COUNT AS SELECT ID1 ,ID2 ,count(*) as COUNT_of_ROW label = "重複行数カウント" FROM DATA_IN GROUP BY ID1, ID2 HAVING count(*) > 1 ; QUIT;
このSQLを実行するとID1とID2のセットで重複しているものだけを抽出できる。
ついでに何行重複していたかをCOUNT_of_ROWに格納している。
重複レコードを取り出す
上記のDUPLICATION_COUNTテーブルができていれば、ID1とID2で元テーブル(DATA_IN)とinner joinしてあげれば、重複しているレコードを取り出すことができる。
【SAS】マクロで戸惑ったこと
SASでマクロを書いたときに、戸惑った覚えがあることを残しておきます。
どうでも良いですがSASでマクロを書くと、(書いたこと無いけど)COBOLとかの昔からある言語はこんな感じかなぁと思ってしまいます。
PUT、INPUT関数
これを%SYSFUNCの中で書いたら、怒られてびっくりしました。
マクロの中ではPUTN、INPUTN関数を使わないといけないです。
他にも、%SYSFUNCで使えない関数は、こんなにあります。
- ALLCOMB
- ALLPERM
- DIF
- DIM
- HBOUND
- IORCMSG
- INPUT
- LAG
- LBOUND
- LEXCOMB
- LEXCOMBI
- LEXPERK
- LEXPERM
- MISSING
- PUT
- RESOLVE
- SYMGET
INTNX関数
今日から1ヶ月後の日付を計算してマクロ変数に格納したいということがあると思います。
このときにINTNX関数を使うのですが、この関数の第1引数でものすごくはまった記憶があります。
たとえば、今日から1ヶ月先の日付を取得したい場合、マクロ以外では
INTNX('MONTH', TODAY(), 1)
と第1引数にクオテーション付きで時間間隔を指定する引数を与えますが、マクロでは
%SYSFUNC(INTNX(MONTH, %SYSFUNC(TODAY()), 1))
と第1引数にクオテーションは不要となります。
Technical Support:nヶ月先の同日日付を取得する方法(SAS 9.1以降)
【SAS】ROC曲線を描く
PROC LOGISTICのオプションではなくて、予測値と実績値が揃っているデータセットに対し、ROC曲線を描く方法。
ここを参考にしました。
http://www2.sas.com/proceedings/sugi22/POSTERS/PAPER219.PDF
DATAIN = データセット名
LOWLIM = データ分割範囲の下限
UPLIM = データ分割範囲の上限
PROB = 予測契約確率
TF = 実績値("0"か"1"の数値)
NINC = 分割数
デフォルトではデータ範囲を20分割してROC曲線を描きます。
PROC GPLOTで図を描いてますが、ROCのデータセットをエクセルにコピーして、エクセルで図を書いた方がそれっぽくなります。
%MACRO ROC(DATAIN, LOWLIM, UPLIM, PROB, TF, NINC = 20); OPTION MTRACE MPRINT; DATA ROC; SET &DATAIN; LOWLIM = &LOWLIM; UPLIM = &UPLIM; NINC = &NINC; DO I = 1 TO NINC + 1; CUTOFF = LOWLIM + (I - 1) * ((UPLIM - LOWLIM) / NINC); IF &PROB > CUTOFF THEN TEST = 1; ELSE TEST = 0; OUTPUT; END; DROP I; RUN; PROC SORT; BY CUTOFF; RUN; PROC FREQ; BY CUTOFF; TABLES TEST * &TF / OUT = PCTS1 OUTPCT NOPRINT; RUN; DATA TRUEPOS; SET PCTS1; IF &TF = 1 AND TEST = 1; TP_RATE = PCT_COL; DROP PCT_COL; RUN; DATA FALSEPOS; SET PCTS1; IF &TF = 0 AND TEST = 1; FP_RATE = PCT_COL; DROP PCT_COL; RUN; DATA ROC; MERGE TRUEPOS FALSEPOS; BY CUTOFF; IF TP_RATE = . THEN TP_RATE = 0.0; IF FP_RATE = . THEN FP_RATE = 0.0; RUN; PROC GPLOT DATA = ROC; PLOT TP_RATE * FP_RATE = CUTOFF; RUN; %MEND;
【SAS】EMのデータをEGで読み込む
EGとEMを同時に使っている環境はわりとあると思う。たぶん。
ただ、EGとEMでデータセットをやりとりしようとすると、なぜかうまくいかないことがある。
そこで、割と無理矢理編み出した感があるデータセットのやりとり手法を忘れないうちに載せておこうと思う。
EG→EMにデータセットを渡す場合
EGとEMが同じSASサーバ上にインストールされている場合は、同じライブラリを見える様にしてあげればEGもEMも中に入っているデータセットを参照できるようになる。
EMでライブラリを指定する場合は、プロジェクトのプロパティにある「プロジェクトの開始コード」にLIBNAMEステートメントを書いてあげればよい。
一番最初に書いたときは、書いたコードを選択して「即時実行」ボタンを押す必要があるが、それ以降はEMプロジェクトを開くときに自動実行されているため、ライブラリは自動で見える様になっている。
あとは、EM側でデータソース作成するときに、先ほど見える様にしたライブラリのデータセットを選んであげれば良い。
EM→EGにデータセットを渡す場合(通常編)
EM上でモデルによるスコアリングをしたデータをEGに渡したいときは、「ユーティリティ」タブにある「データの保存」を使用すれば良い。
データの保存先を先ほど指定したライブラリにすれば、EGからも見える様になる。
EM上ではスコアされたデータを確認するには、モデルノードなどを選択した上で、左のプロパティにある「エクスポート」を押すと、EMが裏で生成しているデータセットの中身を確認することができる。
EM→EGにデータセットを渡す場合(裏技編)
EMはプロジェクトごとにワーク領域を作成して、そこにスコアしたデータなどを全て書き出している。
その領域をEGから強引に読み込みにいくということができる。
以下にその手順を書く。
EM上で書き出したいデータセット名とライブラリ名を把握する
たとえば、「回帰ノード」でスコアされたデータを取り出したいときは、「エクスポートデータ」のTRAINデータが該当する。
この場合、EM上では「EMWS.Reg_TRAIN」と表示されているはずである。
この場合、「EMWS」がライブラリ名で、「Reg_TRAIN」がデータセット名である。
【SAS】プロンプトを使ってみた
この前、とある人からSASの研修資料片手に、「プロンプトって何?」と聞かれた。
正直、そんなのあったっけ?という感じだったので、ちょっとさわってみたら使い方によっては便利だった。
プロンプトの使い方
(SAS EGのスクリーンショットを撮れる環境では無いのであしからず)
以下は、SAS EG上での操作
- クエリビルダや、プログラムを右クリックしてプロパティを開く
- 左のカラムに「プロンプト」があるのでクリックして、「プロンプトマネージャ」ボタンを押す
- プロンプトマネージャで「追加」を押して新規プロンプトを作る
- プロンプトの名前はマクロ変数名と同じようなものなので英語名で付ける
- 表示テキストはわかりやすい日本語にしておく
- プロンプトが作成できたら、プロンプトマネージャを閉じて、プロンプトを追加する
- あとは、プロンプトを使いたい場所(Where句とか)にプロンプトを使ってみる(コードを書いている場合はマクロ変数と同じ扱い)
プロンプトが便利なシーン
プロンプトを使う場面は正直あまり無いと思うが、たとえば、期間をWhere句で指定して、何度も期間を変更しながらTry & Errorでデータを作りたいときなどは、いちいちプログラムを開くより便利かと思った。
【SAS】IFNとIFC
条件によって処理を変えたいとき
普通に考えればif文やcase文を使う。
たとえば、販売金額(sales)10万円以上の場合は、手数料(commission)が2%で10万円未満では手数料が5%みたいな計算をしたいとき、dataステップでは
if sales >= 100000 then commission = sales * 0.02; else commission = sales * 0.05;
SQLでは
case when (sales >= 100000) then sales * 0.02 else sales * 0.05 end as commission