2021年2月1日月曜日

SAS9.4のM7が来てた

 気づかないもんですね…SAS9.4M7が2020年8月に来ていたようです.毎度言ってるんですけど,もうちょっと上手く自分がこの手の情報を拾いたいですね.たまたまでしか見かけたことが無い

sasのhelpのここにありました.メンテナンスリリースによるSAS9.4の拡張って章です.新しい関数やプロシジャと言うよりは調整が主ですかね.一番の見どころはやはりflash関連でしょうか
以下の記載の通りflashの対応したそうですね,M6までの分はflashが終わってから影響ないのか不安ではありますが,まあ1ユーザにはお祈りしかできること無いですね.南無南無

--ここから引用
SAS 9.4M7では、SASオファリングからAdobe Flashの依存関係を取り除くための数年にわたる取り組みが完了しました。Adobe社は、Flashテクノロジのサポートを終了し、2020年末にはFlash Playerの更新と配布を停止すると発表しました。ブラウザベンダは、2019年にデフォルトでFlashを無効にしました。Adobe Flashのサポート終了の詳細については、SASソフトウェアとAdobe Flash Playerの使用についてを参照してください。
--ここまで引用

あとは既知の内容の修正が多いですね.見始めるときりが無いので取り上げませんが,一覧は上がっています.まあメンテナンスリリースですし,新機能の追加よりこっちの方が主になるのが自然に思えます

私がM7を使えるようになるのはいつだろうか…


2021年1月1日金曜日

連続した複数のブランクを1つに削る話

 たまにミスか知らないですけど1つで良いところに2つくらいスペースが入ってるときを見かけます.え?そんなに見ない?
連続した空白の重複を取り除くのって知人のプログラムでは大層なことをやっていたのですが,関数一発で片付くのです…もちろん配列とか駆使すれば何とかなりますけど…

以下の実行ログを見てもらえればいいのですが,compbl関数の紹介です.
aの変数にはhoとgeの間にスペースが3つはいっていますが,compbl関数を通したbの変数ではスペースが1つになっています.あんまり使う機会無いのでいっつも使いたい時には忘れているのですが…
スペースは何個あっても1つになります.スペース自体を消す時はcompress関数ですね

79129   data _null_ ;

79130   a = "ho   ge" ;
79131   b = compbl(a) ;
79132
79133   putlog a b ;
79134   run ;

ho   ge ho ge

NOTE: DATAステートメント処理(合計処理時間):
      処理時間           0.00 秒
      CPU時間            0.00 秒


2020年12月1日火曜日

PharmaSUG2020 TOKYOに参加した話

 昨年参加してからもう1年がたったことに驚きだが今年もPharmaSUGに参加した.今年はコロナもあってオンライン開催.昨年は前日に東京に入って準備やらしたのが懐かしい.家にいると気楽なのはいいのだが「ピンポーン」と誰か来るのはもはやご愛敬.残念午前はQAを見ないといけなかったので呼び出しに応じることはできず客は去っていった.用があるならまた来るやろ.準備にかこつけて普段会えない方と集まるのはいい機会ではあったのだがこんなご時世なので致し方ない.いややっぱり大都会東京のオサレお店でご飯食べたかった.大いに残念である.こんな時くらいしか東京行かないのに.

今年の演題はコロナコロナ&covid19とこんなご時世なのはPharmaSUGの内容にも及んでいる.せっかくの機会で諸々のプロセスを見直したりとか,伝播の状況を可視化したりとかなかなか面白い発表がたくさんだった.いやなにかわかったようなことを書いてしまったが英語パワーが足りないのは昨年と同じで,内容が全然サッパリと言う所が多かった.後で資料見てこんなんやったっけ?となることもしばしばである.
オンラインでの研修はあまり参加したことがなかったので色々難しいことがあったが,まあ無事終わってやれやれ.もしこの他にオンライン開催のイベントがあれば,参加してどういう運営をしているのかを見てみたい.せっかくのコロナと言う機会なのでいろんな開催形態を知っていきたいところ.オンラインと現地の両方で開催,なんてことが普通になるとド田舎の私にとっては,非常に参加の機会が広がって良いなと思うこの頃である.

2020年10月1日木曜日

マクロ変数が空であるかを条件にして分岐させる話

マクロ変数が空かそうでないかでプログラムを分岐できませんか?って聞かれました. ちょっと具体的な状況がピンとこないところですが,とりあえず分岐だけはしたのでここに供養します.
最近sasを触らずsuper excel おじさんになっていたので良い気分転換です.

分岐の時にマクロ変数を空白と比較してあげると空かどうかの判定に使えます.以下で言う所の %if &test = %then %do ; ですね. 以下のプログラムでマクロ変数 testが空の時は空とログに出してくれますし,そうじゃない時はからじゃないよってログに出してくれます.
そう言えば近頃のsasでは%ifが平文で使えるので,いちいちマクロを定義して実行って形にしなくて良く見やすいプログラムがかけますね.

option mprint;
%let test=;
%if &test = %then %do ;
data _null_ ;
  putlog "マクロ変数が空です" ;
run ;
%end ;

%if &test ^= %then %do ;
data _null_ ;
  putlog "マクロ変数が空じゃありません" ;
run ;
%end ;
option nomprint ;

実行ログは以下の通りです.マクロ変数が空なことを示すメッセージのみがログに出ています.
460 option mprint;
461 %let test=;
462
463 %if &test = %then %do ;
464 data _null_ ;
465 putlog "マクロ変数が空です" ;
466 run ;
 マクロ変数が空です
NOTE: DATAステートメント処理(合計処理時間): 処理時間 0.00 秒 CPU時間 0.00 秒
467 %end ;
468
469 %if &test ^= %then %do ;
470 data _null_ ;
471 putlog "マクロ変数が空じゃありません" ;
472 run ;
473 %end ;
474
475 option nomprint ;

このマクロ変数の戻り値に半角スペースって昔は通らなかったんですよね…いつか忘れましたが気づいたら通るようになっていました.便利になったもんです. 通らなかった時はマクロ変数をlength関数に入れて,戻り値が0だったらマクロ変数は空とする.みたいに書いていました.

2020年9月1日火曜日

32bit環境で作ったsasのformatを64bit環境にに移送する話

32bit環境で作ったSASのforamtはそのままだと64bit環境では使えません.データセットは互換あるのですが...使えないでは困る場面があるので移行する方法を紹介します.エンコードとかがすごーくややこしそうな局面と思えるのですが,今回は扱いません.

32bit環境で移行用のファイルを作成し,64bit環境で移行用ファイルを解凍します.移行には32bit環境での準備が要るっぽいので,format含めて移行が必要な場合は早めに準備しておいた方が良さそうですね...たまにcptファイルでデータを頂くことがあるので,その場合は以下の新環境で実行するプログラムを実行するとokです

エンコードの話とか怖くて触れたくない,出会いたくもない.ややこしいのが来ないよう日々祈るばかり.マジで勘弁してくれ

/*>>>>>---------- ここから旧環境で実行 ----------<<<<<*/
LIBNAME CAT32 "移行したいsasデータセットとsasのformatファイルのパス";
filename FILE64 '移行用ファイルを保存するパス\移行用ファイル名.cpt';

proc cport lib=CAT32 file=FILE64 ;
run ;

/*>>>>>---------- ここから新環境で実行 ----------<<<<<*/
libname CAT64 "移行後のデータセットを保存したいパス" ;
filename FILE64 "移行用ファイルを保存するパス\移行用ファイル名.cpt" ;

proc cimport lib = CAT64 file = FILE64 ;
run ;

2020年8月1日土曜日

SGPLOTでバタフライプロットを書く話

最近グラフおじさん化していますが世の中のグラフの種類の多さにたまげる毎日です.知らないグラフがいっぱいある.困る.今回はバタフライプロットをSGPLOTで書いてみます.我流なのでもっといい方法があるかもしれません.もっと違う書き方あるよってご存じの方はぜひコメントにて教えてください.

バタフライプロットとは以下のような真ん中から両端に向かって伸びる棒グラフです.見たことはありましたが先日初めて名前をしりました.

 
早速上のグラフを書いたプログラムを貼りますが,x軸は頻度なのでまず数えます.頻度を出したデータの内,左側(青い方)に出したいものは-1をかけて頻度を無理やり負の数にします.そのままSGPLOTに読み込ませて,x軸ラベルの表示を正の数に変えれば完成です.
 
proc freq data= sashelp.class noprint;
  tables sex * age / out = V_CLASS ;
run ;
 
data V_BF ;
    set V_CLASS ;
 
    if SEX = "男子" then do ;
        V_CNT = COUNT * -1 ;     /*頻度を負の値に変換*/
        V_SEX = 1 ;
    end ;

    if SEX = "女子" then do ;
        V_CNT = COUNT ;     /*頻度はそのまま*/
        V_SEX = 2 ;
    end ;
run ;
 
proc sgplot data = V_BF  ;
    hbar AGE / response=V_CNT group = V_SEX barwidth = 1.0;
 
    xaxis
        values=(-5 to 5 by 1)  /*データ上は-5から5まで*/
        valuesdisplay=("5" "4" "3" "2" "1" "0" "1" "2" "3" "4" "5") /*メモリの表示を指定*/
    ;
    yaxis
        values = (10 to 20 by 1)
        grid   /*格子線あった方が多分見やすい*/
        reverse  /*y軸の値の並びを大から小にする*/
    ;
run ;
 
マイナスでデータを持たせて左右に表示して,軸のメモリ表示は正の値として指定するのってなんだかイマイチな気がします.わざわざ手でメモリ値を指定するのて結構煩雑ですし…いい感じに指定する方法があればいいんですが,どなたかご存じないですか?

 

2020年7月1日水曜日

defineのピナクルチェックのerrorですげーてこずった話

気づけば簡単なんですが,errorの原因に気づかずに時間かかったのでここで供養します.なむなむ

defineをピナクルでチェックすると以下のerrorが出ました.ほうほう参考資料が無いのねと思って確認すると,確かにdefineにリンク貼り忘れたものがあったので追加しても以下のerrorは消えなかったのです.

Pinnacle 21 ID:DD0015
Message       :Referenced Document is missing
Severity      :Error
Found         :1

何で消えないのかわからなかったのでreportのdetailを見に行くと以下の通り.
最初から見に行けと言う話は横に置いて,error箇所はdefineの最終行,valuesはnullと何のことかさっぱりです.足りない参考資料は入れたので参考資料が無いよ!のnullではないのは明らかです.

Variables:Line Number: defineのソースコードの最終行
Values   :null

正解はdefineの参考資料をリンクする際に記載するIDに誤記があったことでした.誤記していたためそんなID無いよ!ってerrorを出していたようです.
defineに参考資料をリンクする際には,最初の<def:SupplementalDoc>タグで参考資料のIDを定義して,本文中でそのIDを参照します.

正しい状態だと以下になります.leafIDが1回目と2回目でhogehogeと一致しています.
<def:SupplementalDoc>
    <def:DocumentRef leafID="hogehoge"/>
</def:SupplementalDoc>

<def:DocumentRef leafID="hogehoge">
</def:DocumentRef>

今回のerrorの原因は以下の状態になっていました.
後半で指定したpiypiyoはSupplementalDocタグで指定していないです.
<def:SupplementalDoc>
    <def:DocumentRef leafID="hogehoge"/>
</def:SupplementalDoc>

<def:DocumentRef leafID="piyopiyo">
</def:DocumentRef>

誤記をするなと言う話なのですが,末尾に1つだけerrorを返すのではなくせめて一致しないIDの数くらい教えてほしいです…今回は誤記があったのが3つだったので,最低でも3つはあったはずです…1つしかerrorはないって言われていたので,defineの中で1つしかなさそうなものからerrorの原因を探していました…