2018年8月15日水曜日

プログラムをデバッグする話

データステップにデバッグオプションを付けると,デバッガが起動します.
1stepごとに実行し適宜変数の値を確認したり,指定した箇所まで実行したりすることが出来ます.
excelで言う所のデバッグトレースですかね.

以下のプログラムを実行すると,データステップにdebugオプションが付いているので
データステップデバッガが起動します.

data hoge  ;
    val1 = 1 ; val2 = 2 ; type = "A" ; output ;
    val1 = 1 ; val2 = 2 ; type = "B" ; output ;
    val1 = 1 ; val2 = 2 ; type = "C" ; output ;
run ;

data hoge2 / debug ;
    set hoge ;
    if TYPE = "A" then VAL3 = VAL2 - VAL1 ;
    if TYPE = "B" then VAL3 = VAL2 + VAL1 ;
    if TYPE = "D" then VAL3 = VAL2 * VAL1 ;
run ;





 





  















デバッガが起動すると,debugger log とdebugger sourceの二つのwindowが立ちあがります.

debugger logの下部にある点線の下にコマンドを入力し,デバッグを行います.
debugger sourceの黒線部分が今実行する直前のステートメントです.

ココで出来ることは,以下の感じです.
もちろん他にも機能はありますが,とりあえずこれだけです.
  • 指定した行数分ステートメントを実行(stepコマンド)
  • 指定した変数の値を確認(examineコマンド)
  • ステートメントを指定して,そのステートメントまで実行(breakコマンド)
  • 指定した変数の値が変わるまで実行(watchコマンド)
  • デバッガを終了(quitコマンド)
breakコマンドはexcelで言う所のbreakpointとほぼ同じだと思います.
 デフォルトではエンターキーがstep1に対応しているので,
debugger logでエンターをたたくと1ステートメントだけ実行されます.
以下の画像ですと134行目に黒線があるので,133行目まで実行されている状態です.
この状態でexamineコマンドでVAL3を見ると,値が1になっています.
examineコマンドは黒線がある直前まで実行された段階での変数の値を返してくれます.
ですのでdebugger logにステップ:行132カラム24の時にすべての変数の値を確認すると,VAL3は欠測になります.
(まだ132行目のTYPEが"A"の時にVAL3を演算する処理が実行されていないため.)
 _N_=1のため,今は1レコード目を読みこんでいる状態でデバッグをしていることが分かります.

データステップデバッガも例にもれず,1レコード読みこんで,すべてのステートメントを実行して,
また次のレコードを読みこんで...と進んでいきます.
確認したいレコード番号が大きいとそこまで実行しないといけません.
いちいちエンターキーを叩いて1レコードごとに実行しているとキリが無いので,
watch,breakなどを駆使して確認箇所まで実行するのが良いのではないでしょうか.



















マクロのデバッグにも使える感じですね.

参考資料
<http://www.sas.com/offices/asiapacific/japan/service/help/pdf/lebaseutilref.pdf>
dataステップデバッガの項目

SASユーザー会行ってきました

今年もSASユーザー会行ってきました.
台風がかすっていきましたが,まあ何とか全日程が完了してよかったです.

1日目は台風とともに東京に向かうことに.
前日入りも覚悟していたところでしたが,東にそれたと聞いて当日東京に向かうことに決定.
霧雨の舞う中会場にたどり着き,荷物はびしょびしょ.
雨が風で舞う所為で傘がその機能を果たしてくれず,それはそれはぬれました.
一日目はルームDを中心に発表を聞く.
ODS TABLE,rtf作成時のfont調整等々なかなか便利そうなものばかり.
fontの調整はあの発表をそのままパクってしまおうかな...

セッションが午後のみだったのであっという間に一日目は終了,懇親会へとなだれ込む
雨の中の移動にエネルギーを思ったより使ったのか,ご飯を見るとおなかがみるみる空いてくる.
乾杯の挨拶中に食べたいものにあたりをつけ,乾杯後に早速ご飯をget
周りを見ると先輩が知り合いを連れてきて後輩が群れを成して名刺交換にいそしむ光景がちらほらありましたが,そんなものは知らぬ.おなかが空いている.

台風が明日にでも命中するとの予報だったので,2次会も無く解散しホテルへと引き上げる


2日目はもはや台風の気配など無く普通に晴れ.
全日程にわたる雨を覚悟し,折り畳みではないかさを持ってきた私は拍子抜けしました.
自分の準備が出来ていなかったので,直前のセッション中に準備をして何とか間に合わせる.
どうもやっつけな準備をしたせいか発表もやっつけに終わってしまった気がするが,終わればいいのだ終われば.

自分の発表を終えるとイマイチ気が乗り切らず,ほどほどにセッションを見てほどほどに切り上げるとする.
東大の中央食堂に乗り込むとそれはそれは綺麗で広大で自分の学生時代との差に悲しみを背負うが,
悲しみも早々に忘れてデザートをパクついて糖分を補給,悠々と会場に戻って最後のセッションを見て今年のユーザー会もお開きに.

今年のノベルティは扇子,拡大鏡,メモ帳の三択でしたが,
扇子以外にもらうものが無かったので実質一択.メモ帳もらっても...ねえ...?
しかしSASユーザー総会,椅子をですね,もう少し増やして欲しいなと思いますね.頼むわ.

会の後は知人との飲み会が新橋であるので急行し,安居酒屋でチャーハン,ジンジャーエール,モツポン酢をいただく.
ジンジャーエールはもう少し辛口のほうが私の好みであったが,所詮安居酒屋.高望みはすまい.
知り合いも変わりなくSASとは全然関係ない話に華を咲かせ,23時頃にホテルに引き上げそのままお布団へ.

9月にPharmaSUGがあるので,次はそのタイミングで東京にいくとしましょうかね.
申請やら報告書がめんどくさいので有給で行きたいが,果たして申請が通るかどうか.
通って欲しいなあ.

2018年6月24日日曜日

SAS飲み会に行ってきたお話

なにやら大層なブログタイトルになってしまいましたが.
単にネタを持ち寄りましょう,という簡単な会に6月23日に行ってきました.

18:30開始,会場が梅田となってはそこそこ早めに会社を出ないと行けません.しかしプログラム書いてると意外と遅くなり,すわ遅刻か.となりながらも退勤.会場へ急ぐ.

道中急いでいたため軽食と飲み物のことをすっかり失念しており,はたと思い至ったときには時すでに遅し,あたりにコンビニはない.これは21:30まで飲まず食わずかと覚悟を決めるが,自販機を発見しお茶を買うことには成功する.軽食は無く空腹と共に人の発表を聞くか...とがっくり肩を落としながらも引き続き会場へと急ぐ.

当日の会場がわかりにくいビルで,ビルにたどり着くまでに同じ道を行ったり来たり.この筋のはずなんだがなぁとウロウロし,なんとかビルを見つけて(なんと2度もそのビルの前を素通りしていた)建物内に入る.
なんと建物の中でも迷子になってしまい,あちこちさ迷い歩く羽目に.壁に並ぶ不審者に注意の張り紙が大変心に響いた.

ほうほうの体で会場へin.全員揃うのをまち,本日のネタお披露目が始まる.

私は今回はsgplotのオプションをいくつか紹介すると言う,目新しさのかけらもない微妙なネタを持っていきました.

私のは手垢のついたネタなのでいいのですが,classdataオプション(proc means)やweightステートメントのzeroオプション(proc freq),果てはフレームワークのようなもの(プログラムの定型部分を自動で行うなど)などと出るわ出るわ盛り沢山ですね.

classdataオプション,存在は知っていましたが使ったことなかったですねー.いっつもダミーデータをmergeしてましたね...一度使ってみましょう.

次は忘年会のシーズンに集まる感じですかね.またその時はどんなネタが出てくるか,今から楽しみです.

最後になりましたが,来てくださった皆様,これなかった皆様,ありがとうございました.

2018年6月15日金曜日

call is8601_convertルーチンの話

is8601_convertコールルーチンは,日付や2つの日付の間の間隔をiso8601フォーマットに変換します.
この日付の間隔のことを,デュレーション値と呼ぶようです.
たとえば始点が4月1日,終点が4月2日のとき,デュレーション値は1日です.
第一引数に変換前の値に何が入るかを指定し,第二引数に変換後の値が何であるかを指定します.
第三引数に変換前の値,第四引数に変換に使う値,第五引数に変換後の値を格納する変数を指定します.

第一引数に'du/dt'と指定すると,第三引数にデュレーション値,第四引数に日付を指定します.
これが逆になるとエラーが返ります.
同様に'dt/du'と指定すると,日付→デュレーション値の順に指定をしないといけません.

とてつもなくわかりにくいので以下にいくつか具体例を示します.

data _null_ ;
  format hoge e8601dn. ;
  /*変換前の値はデュレーション値と日付,変換後に期間の開始日を出力,期間は8週間,期間の終点は2018年1月1日*/
  call is8601_convert('du/dt' , 'start' ,"p8w" ,"2018-01-01" ,  hoge ) ;
  putlog hoge = ;
run ;

hoge=2017-11-06


data _null_ ;
  format hoge e8601dn. ;
  /*変換前の値は日付とデュレーション値,変換後に期間の終了日を出力,期間の開始日は2018年1月30日,期間は8週間*/
  call is8601_convert('dt/du' , 'end' ,"2018-01-30" ,"p8w" , hoge ) ;
putlog hoge = ;
run ;

hoge=2018-03-27


data _null_ ;
  length hoge $20 ;
  format hoge $n861b. ;
  /*変換前の値に日付と日付,変換後はデュレーション値,期間の始点は1月30日,終点は3月14日*/
  call is8601_convert('dt/dt' , 'du' ,"2018-01-30T12:30" ,"2018-03-14T14:45" , hoge ) ;
  putlog hoge = ;
run ;

hoge=P1M15DT2H15M

2018年5月23日水曜日

ods rtfでのファイル名の上限の話

何やら身辺が立て込んで仕方がないです.

ods rtfではパス名とファイル名の合計文字数は180文字が上限のようですね.
windows上の制限は256文字なので,上限いっぱい使ってもまだ余裕があるみたいですが.

ただパス名込の文字数なので,76文字以上のフォルダに移動するとwindowsでの制限に引っかかりますね

180文字を超えた名前を指定すると,
無効なファイル名です,致命的なODSエラーが発生しました.のerrorが返ります.


2018年4月9日月曜日

putlogでlogに任意の値を出力する話

putlogをご存知でしょうか.logに任意の文字列を出力するステートメントです.

これを使ってデータの中のイレギュラーデータを(ある程度)見つけようと言う試みです.
ためしに下のデータセットがあるとして,変数aには欠測は本来入らないと仮定してください.
その変数aに欠測が入ってるかどうかと,欠測の時のほかの変数の値をlogに出力するのが以下のプログラムです.
私は最近知っていたく感動したのですが,普通にご存知の方が多いのでしょうかね...?

putlogで指定した変数の値が出力できるので,それを利用した形になります.
自分で指定した条件に該当するレコードがなかった場合,logには何も出てきません.

"E" "RROR"とputlogに指定しているのは,ログには"ERROR"と出したいが,
ログに出す条件のレコードが何もないときはERRORとログに残したくないためです.
涙ぐましいですね.この小細工が.

/*---------- ここからプログラム ----------*/

data hoge ;
 a = 1 ; b = 1 ; c = 6 ; output ;
 a = 1 ; b = 2 ; c = 5 ; output ;
 a = . ; b = 3 ; c = 4 ; output ;
 a = 1 ; b = 4 ; c = 3 ; output ;
 a = . ; b = 5 ; c = 2 ; output ;
 a = 1 ; b = 6 ; c = 1 ; output ;
run ;

data _null_ ;
  set hoge ;

 /* -- 想定の値以外(今回は欠測)があるときにlogに出力 -- */
  if a = . then do ;
    putlog "E" "RROR_A" ;
    putlog b = c = ;
  end ;

run ;


2018年4月4日水曜日

ルール間違ってた

「pandemic」というボードゲームにリベンジしてきました.
致命的なルールの勘違いをしていたことに気づいてしまいました.
4戦全敗した後でですが...
規則の確認を雰囲気でやってはいけない好例です.

このゲーム,ワクチンを作って病原菌を根絶(盤上から赤青黒黄の四色の駒を完全に取り除くこと)したら勝ちだと思っていたのですが,ワクチンを4種作った段階で勝ちなのですね.そら勝てないね.

ワクチンは一枚目の画像の版下部にある,なんか四角い四色の駒ですね.
一枚目の画像は赤のワクチン駒を獲得する前に時間切れで負けです.















2枚目は一応勝ちの状態です.盤下部に赤青黄黒の四角いワクチン駒を獲得できています.
しかしこれは参考程度です...手放しで喜べない勝ちなのです...
本来ランダムに決まるプレイヤの役職を,事前に選んでプレイしましたからね...
普通に勝利は次回に持ち越しですね...