2018年10月1日月曜日

sgplotで使うsymbolの紹介

SGPLOTでグラフを書く時,群毎にグラフにsymbolを出すことがあると思います.
どんなsymbolが使えるかをすぐ忘れてしまうので紹介します.
よく使うのは丸と四角と三角ですかね.下の図に乗せています.

その他のはonline docを参照してください.
https://documentation.sas.com/?cdcId=pgmsascdc&cdcVersion=9.4_3.3&docsetId=grstatproc&docsetTarget=p0i3rles1y5mvsn1hrq3i2271rmi.htm&locale=ja

/*test data*/
data HOGE ;
  do G = 1 to 6 by 1 ;
    do A = 1 to 3 ;
      B = G ;
      output ;
    end ;
  end ;
run ;

proc sgplot data = HOGE noautolegend ;
  styleattrs
    datasymbols=(Circle CircleFilled Square SquareFilled Triangle TriangleFilled)
    datacontrastcolors=(black)
    datalinepatterns=(solid)
  ;
  series X = A Y = B
    / group = G markers
  ;
 
run ;


2018年9月6日木曜日

Phrma SugのSDEに行って来た話

東京でやると言うもんだから早々に行くことを決意,さっさと予約を済ませる.
しかしよく見ると受付が9:30~10:00,関西から行くにはいささか時間が早いので夜行バスで向かうとする.
結果的にここで夜行バスを選択したのが吉と出た.

迎えた当日,台風「こんにちはー」
SASユーザー総会の時も台風と一緒に東京に行った記憶がよみがえる.
すわ電車運行見送りかと震えるも私は夜行バス.前日に東京に入っていたので大した影響は受けなかった.

建物に入ればこちらのもの.恙無くSDEが始まった.
プロジェクタが何を思ったか赤を青に,青を赤に表示している所為でSASのアイコンが赤い.違和感違和感.
中国の規制当局の話が一番興味深かったが残念英語がイマイチわからない.
うーんこのと聞きつつ,英語の聞き取りは練習したほうがいいなあと実感した.
後はまあ人工な知能をpythonで実装した話の事例である.実に最近のブーム.
RでPPTへの出力,との内容も面白そうではあるがバリデーションの壁は厚く高そう.

うちの大将のポスターセッションも見てきたがやはり大将は話がうまい.
あれくらい話せるようになればなあと思うも,練習あるのみか.
いや人前で話すのは苦手なんだが

終わる頃には風が荒れる空模様だったが雨は無く,後楽園で知り合いと飲んで事故も無くホテルに引っ込む.
どうせ台風で交通機関荒れるからと一泊して本当に良かったと思いつつ12:00頃に就寝.
風が轟くもなんのその,すぐに夢の世界へとさようならし,翌日の昼過ぎに東京に別れを告げた.

自宅の隣家のブロック塀が見事に崩落している様に絶句するも,家は無事で何よりであった.
次は来年のSASユーザー総会まで何も無いかなあ,しかし東京に行くのはお金がかかって仕方が無い.
今回のSASグッズはSASのリングNOTEだった.結局もったいなくて使えずそのまま放置するんだろうなあ.

2018年9月1日土曜日

プログラム実行時にログウインドウを常に前面に表示する話

何かプログラムを実行するとログが表示されますよね.
プログラムを書く時は拡張エディタを大きくしたいけど実行時にはログ画面を大きくしたい...
そんなとき,あると思います.
パソコンの画面が小さいと,拡張エディタを大きくするとログ画面がエディタの後ろに行ってしまうので,実行時にログ画面をクリックして最前面に持ってくる謎の1手間が必要になります.
画面が十分に大きければ問題ないんですがねえ...
以下のオプションを設定すると,プログラムを実行する時に
自動でログ画面が最前面に出てきてくれる様なります.
実行時に勝手にログ画面が前に出てきてくれるので,ログの確認時に地味に助かっています.
ログ確認後に再度プログラムを修正する時は拡張エディタを選択しないといけませんが.
  1. logウィンドウをクリックして選択する
  2. ツール→オプション→ログ→「表示タブの新しいデータが表示されたときにウインドウを前面にする」
にチェックを入れる
これでOKです.個人的にはなかなか気に入っているオプションです.

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