The Nameless City

何故か製薬やSAS関連のブログ、の予定。

ほとんどのプロジェクト失敗の原因はコミュニケーション不足、とか言われるその先を考えてほしいなと。

愚痴っぽいメモ。
google:プロジェクト 失敗 コミュニケーション不足


失敗気味であればあるほどコミュニケーションは阻害される。コミュニケーション不足は擬似相関な要因で、兆しを見付けたらなにかがおかしいので別の所の故障原因を探すのが吉。
「コミュニケーションしろ!」と声掛けても飲み会開いてもあんまり上手くいかないよね。


誰かをワルモノにしない問題点とか対応策探しは大事。
酷ければ、もっと上の人をワルモノにするとかやりようは幾つかあるけど。
監査スキームはあまり上手くいかない事が多い。Audit Trailの作成作業が手作業ってのは良くない(リソース不足とかで作らされる事はあるが)。
チェックスキームを自動化して毎日ぶん回してダッシュボードで作業者が確認する、くらいがホントはいいよなあ。人間の脳内にタスクを置く意味あんまりあるとは思えず。


そういう事がやりやすい、一つのプラットフォームを何か準備しておきたい所で、それがRedmineのカスタマイズやなにかで回せるならいいけど、多分難しいだろうなあ。
GitHubとかで治験の作業をプロトコル単位で回したい。WordやExcelファイルに拘束されるのは良くない。

Windows PowerShellのイマイチイケてない所。

バージョンの差異が少なからずあり、Win7とWin10ではバージョンが違う。

最大の欠点がこれで、当面WindowsDOSコマンドから抜け出せないのもこのせい。
正直当てに出来ない。

未だにシェルの文字エンコードS-JIS

Winの、「表示はS-JISなんだが実際には裏はファイル名やファイルパスはUnicodeで~」という仕様がしんどい。
chcp65001でシェルを使おうとして、Unicode対応フォントが当てられないのも困る。

エイリアスが外部の実行ファイルとかぶる。DOSコマンドとの非互換性がきつい。

lsが使えるのになーという所が。
cdが/dを受け付けない。iexと打ったらエイリアスに蹴られる。

セキュアな仕掛けがシェルとしての利用を阻む事が・・・・・・

いやまー、パスワードとか埋め込めないのは正しいっちゃ正しいんですがね。

パスワードルール、変わっていくと良いんですが。

パスワードの定期変更推奨が無くなりました。総務省から。


当面は、Part11とかの影響引き摺るんでしょうが、今後は無くなりそうです。
その代わりと言ってはなんですが、ユーザーの管理はしっかりやってく必要あるでしょうね。

WinでのPython入れ。

Python入れる。

現行Py3系統の最新安定版は3.6.4。公式版、64bitを使う。
ただ、実際のところ32bit版が安牌な気がするが要調査。

Proxy通す。

会社内で使っているプロキシを通す、のだが、PACファイルでProxy設定しているパターンなので、それはそのままは使えず。
念の為いうと、PACファイルのはnetsh winhttpコマンドでも取れず。LinuxでもGNOMEのsettingで一部対応はしているけど、認証付きProxyにはうまく対応しないなど色々ある。
基本的にここ、pipの設定ファイルで設定してpipコマンドにだけproxyを~というところなのだろうけど、会社環境ではそもそもコマンドのパラメータにある--proxyでうまく設定できなかった。
なので、「UNIX系アプリで使われる古くからのProxyの設定方法」で試すと通った。

set HTTP_PROXY=http://<user>:<password>@<server>:<port>
set HTTPS_PROXY=http://<user>:<password>@<server>:<port>

なお、@は%40として対応。pipとかのproxyの設定で上手くいかないのは、このあたりの特殊文字の扱いのせいかも。
この設定は、アップデートなんかはWin/個人レベルという事で、環境変数としてもそちらで設定しておいた。サーバ再起動は不要。


なお、Linuxの場合、プロキシ設定がどんどん進化はしているので、環境に合わせて設定した方がいいと思うし、それが疲れると思うならpip.confとかのやり方をやるのがいいと思う。
このやり方は暫定的なやり方で、Winのプロキシ認証とかちゃんとお作法に則りたいところなんだけど、Pythonのインストールモジュールではそこまで考慮しないので、環境変数にハードコーディングしているような感じに。

pipアップグレードしておく。

実際には、「pip install pip --upgrade」としても、入ってますーとか言われて終わるかと思う。

wheel入れる

コンパイル済みのモジュールを入れる為。

numpy+mkl.whlをダウンロード。

これは何?

全部pythonで完結してりゃ楽なんだけど、実はそうはいかないという事がある。そこが、mklのところ。
Intel Math Kernel Libraryの簡単な言い方っぽい。x86x86-64AMD64)版があるがそれをインストールしてnumpyにそれ参照するように設定して~というやり方は今回せず、
https://www.lfd.uci.edu/~gohlke/pythonlibs/
からのnumpyに組み込んだpre-build版を使う。Intel Math Kernel Libraryのところからダウンロードするのが登録必要で面倒臭い為(フリーではあるけど)。pre-build版はUnofficialなので自己責任でどうぞ。

この入れ方について。

こちらはデータサイエンティストとデベロッパーのあいのこみたいなものなので、こんな感じで入れておく。
家ではFedoraだし。
Anacondaは、一人で一台みたいな状況であれば別に問題はないんだと思うけど、余計な環境変更を行う事があるらしく、トラブルの元にもなるようなので止めておく。

ダウンロードしたファイルを特定フォルダに入れて、pipでインストールする。ローカルのソースをインストール出来る。

他インストール。

numpy、scipy、wxPythonとか。djangoとか。
pyenvとかは今回はやってない。特に複数バージョン云々やらんつもりで。あと、pyenvはWinは無理だったそういや。

SAS開発環境に、Atom Editorを使うことのとりとめないメモ。

SASIDEと呼べるのは、SAS謹製しかない。

WDSとかは置いておいて。University Editionは商業利用出来ないし。
コードエディタとしてはSAS DMSの他、SAS Drug Developmentの~とかSAS Studioとかあるが、如何せんライセンスの問題もあるし、何より、SAS Intelligence Platformのサービスが立ってないと動かんものが多い。で、これは、起動前のクレデンシャルの問題とかをどうするか決めておく必要があるし(AD連携は可能なんだけど)、実行結果を貰う側がどうやって貰うかも考えておく必要があり、それも含めて今はSAS謹製のものを利用する以外はあんまり解がない状況ではある。


Eclipseプラグインとかは、AppDev Studioのライセンスにくっついて来た。あんまり深くは調べていないが、JavaからSASを呼べる・使えるというところで、多分これもSAS Intelligence Platformが必要だなあと。しかもJava用であり、SASをそのまま実行させる用ではない。。。。。。


結論としては、あくまでも他のアプリ使うのは、エディタの範囲までかなと思う。
同一マシンにおけるなら、SAS入れたサーバにリモート実行しかけることができるなら、バッチ実行までは大丈夫だけど、sshみたいな仕掛けがWindowsの標準ではかなり穴が開いてないのもあって難しいしわかりづらい。PowerShellで出来るんだけどさ。。。。。。psexecはハマりがキツくて非推奨。

SASのEditorとしては。

各種テキストエディタは適当に使え、なんだけど、テキストエディタではやはり能力に限界がある(色分けくらい)ので、プログラムエディタくらいは投入したいところ。
今想定しているのはAtom Editor。
設定には一癖二癖あることもあって、VS Codeも見てみたが、野良で機能を突っ込むにはAtom Editorの方が楽だろうとは思っている。現行環境では外部パッケージを取り込むことは出来ているので、あとはautocomplate機能、language-sasのもうちっとのカスタマイズ、辞書機能の利活用どうするの問題をクリアできればなあ。
ただ、正直サクラエディタgrep機能が便利過ぎてなあというのと、Atom文字エンコーディングのデフォルトがUTF-8というので、日本のSASの標準的にはS-JISな環境ではうまくいかないかもしれない。

DMS動かしつつ、裏でバッチ実行するというやり方。

と言っても大げさなものではなく、
単純に、SASUSERのパス変えた違うsasv9.cfgで実行させればいいという話です。
パラレルにバッチ実行するには、rsasuserシステムオプションと、ods pathのパスの最初にWORK.TEMPLATEとかをprependしてやればよいです。ちょっとのコマンドであれば、autoexec.sasではなくsasinitstmtで実行させられます。

コードリストになっている文字列から、コード値の数値に変換する方法

要約

コード変換については、SASの場合にはフォーマット/インフォーマットを使うのが楽です。

数値コード→文字列変換
数値フォーマットを使います。
文字列コード→文字列変換
文字フォーマットを使います。
文字列→数値コード変換
数値のインフォーマットを使います。

インフォーマットとは。

聞きなれない言葉かもしれませんが、、、外部の文字列を取り込んでSASの変数に格納する際に適用される、フォーマットの逆みたいなやつです。
普段はあんまり使わないんですが、CSVからデータ取り込みするとかの場合に適用されます。
また、ほとんどの場合にはフォーマットと対になるインフォーマットがあるんですが、例外も結構あります。
日付型のYYMMDD10.フォーマットは、亜種にYYMMDDS10.フォーマットとかあるんですが、インフォーマットはYYMMDD10,インフォーマットしかないです。スラッシュ区切りでもYYMMDD10.インフォーマット使えばいいのですが。

作り方

こんな感じ。

/* S-JISでやってます */
proc format ;
  invalue _SEXI '男子'=1 '女子'=2 ;
quit ;
data CLASS ;
  set SASHELP.CLASS ;
  attrib SEXN length=8 label='SEX (N)' ;
  keep NAME SEX SEXN ;
  SEXN = input(SEX,?? _SEXI.) ;
run ;
proc print data=CLASS ;
quit ;
OBS    Name            Sex     SEXN

  1    アルフレッド    男子      1
  2    アリス          女子      2
  3    バーバラ        女子      2
  4    キャロル        女子      2
  5    ヘンリー        男子      1
  6    ジェームズ      男子      1
  7    ジェーン        女子      2
  8    ジャネット      女子      2
  9    ジェフリー      男子      1
 10    ジョン          男子      1
 11    ジョイス        女子      2
 12    ジュディー      女子      2
 13    ルイーズ        女子      2
 14    メアリー        女子      2
 15    フィリップ      男子      1
 16    ロバート        男子      1
 17    ロナルド        男子      1
 18    トーマス        男子      1
 19    ウィリアム      男子      1

注意点

このままだと、実はアサインされていない文字列の場合には、bestで適当に数値変換されてしまいます。
通常は文字列を数値に変換しても問題ないのですが、たまたま数値にうまく変換出来る場合であると、変な事になります。

proc format ;
  invalue _SEXI '男子'=1 '女子'=2 ;
quit ;
data CLASS ;
  set SASHELP.CLASS ;
  attrib SEXN length=8 label='SEX (N)' ;
  keep NAME SEX SEXN ;
  if SEX = '男子' then SEX='3.14' ;
  SEXN = input(SEX,?? _SEXI.) ;
run ;
proc print data=CLASS ;
quit ;
OBS    Name            Sex     SEXN

  1    アルフレッド    3.14    3.14
  2    アリス          女子    2.00
  3    バーバラ        女子    2.00
  4    キャロル        女子    2.00
  5    ヘンリー        3.14    3.14
  6    ジェームズ      3.14    3.14
  7    ジェーン        女子    2.00
  8    ジャネット      女子    2.00
  9    ジェフリー      3.14    3.14
 10    ジョン          3.14    3.14
 11    ジョイス        女子    2.00
 12    ジュディー      女子    2.00
 13    ルイーズ        女子    2.00
 14    メアリー        女子    2.00
 15    フィリップ      3.14    3.14
 16    ロバート        3.14    3.14
 17    ロナルド        3.14    3.14
 18    トーマス        3.14    3.14
 19    ウィリアム      3.14    3.14

これを回避するのには、ちょっと仕込みがあります。
otherの設定をしてやると良いです。

proc format ;
  invalue _SEXI '男子'=1 '女子'=2 other=. ;
quit ;
data CLASS ;
  set SASHELP.CLASS ;
  attrib SEXN length=8 label='SEX (N)' ;
  keep NAME SEX SEXN ;
  if SEX = '男子' then SEX='3.14' ;
  SEXN = input(SEX,?? _SEXI.) ;
run ;
proc print data=CLASS ;
quit ;
OBS    Name            Sex     SEXN

  1    アルフレッド    3.14      .
  2    アリス          女子      2
  3    バーバラ        女子      2
  4    キャロル        女子      2
  5    ヘンリー        3.14      .
  6    ジェームズ      3.14      .
  7    ジェーン        女子      2
  8    ジャネット      女子      2
  9    ジェフリー      3.14      .
 10    ジョン          3.14      .
 11    ジョイス        女子      2
 12    ジュディー      女子      2
 13    ルイーズ        女子      2
 14    メアリー        女子      2
 15    フィリップ      3.14      .
 16    ロバート        3.14      .
 17    ロナルド        3.14      .
 18    トーマス        3.14      .
 19    ウィリアム      3.14      .

SASでEXCELを取り込む場合、DDEでファイルを取り込むと、セル内改行文字でぶった切られる件

SAS9.4で確認。


どうにか回避出来ないものかと思って色々考えたんですが、infileステートメントでどうにもtermstrとか指定出来ないですし、別レコード判定がされてしまっているようで。
仕方ないので、改行文字の入っていないセルだけを取り込む形で回避しましたが、どうにも不格好だなあ。


EXCELファイル取り込み、幾つか方法があります。

SAS/ACCESS Interface to PC Files経由
PROC IMPORTでDBMS=EXCELで取り込む方法。SAS/ACCESS Interface to PC Filesのライセンスが必要です。また、SASのbit数とOfficeのbit数が合わない場合には、PC Files Serverを立てる必要があり、かつ、EXCELCSエンジンとか使う必要が出て来ますし、コントロール出来るレベルが変わります。
DDEで取り込む
DDEは古いデータ交換方式で、どちらかというと、動いているアプリケーション間でのデータのやり取りに使われるのですが、廃止されてはいませんが、あんまりセキュアではないです。DDEを使ったExploitはあります。ただ、今でも、Excel文書のリンク機能なんかはDDEで行われたりしているので、完全廃止とかになる可能性は薄いかと思います。


SASのDDE特有かもしれませんが、XWAIT/XSYNCとかをNOにしておかないと、バッチ形式であってもプロセスが停止したりしますね。
このあたりも問題で、Windowsのセッション内でSYNCでない状態で別プロセスでExcelを起動しそこと非同期で実行するのに、不確実なsleep関数を仕込む必要があるとか、ちょっと良くないやり方にはなってます。


Excelのセル内改行の問題は、昔からいろんなアプリで「対応していなかった」のですが、Excelのデータを例えばCSVやTSV(という言い方はあんまり一般的ではないですが、タブ区切りのテキストファイル)に保存して読み込む際でも再現出来ないというオチがあり、ある意味仕方ないのですけど、ですけど。。。。


暇になったらマクロでも作ってみようかと思いますが、多分SAS/ACCESS Interface to PC Filesとかでは回避出来るんじゃないかというのと、そもそもそれはSASで頑張りすぎじゃないか(Excel側でやるのがみんな幸せになれると思います)というので、優先度は低め。

サーバのSAS環境に源ノ角ゴシック Code JPを入れたい。

SASプログラムで、私結構一重引用符使うのですが、
MSゴシックだとこれがカンマと混ざるのが辛い。


源ノ角ゴシックを拡張エディタで使いたいなあと思うのですが、如何せん共有サーバだと厳しいっすなー。
SAS自体に仕込むんじゃなくて、あくまでもエディタ設定に仕込みたいだけなので、悪影響はないと思うんですけどね。
ちょっと話してみたいですが、検証環境がない故に試しにくい見せにくいのが困りものです。

SDTMとかADaM触っててイライラする事

SAS V5 Transport fileの制限ではあるが、

  • 変数名8文字まで

というのが、プログラムにおいて大変質が悪い状況を発生させてる。
変数が認識しづらいし、サジェスト機能を作るにも不便きわまりない。


やっぱまともなプログラマーが設計とかに関係しないとダメですね。

連続性の補正、という言葉について。

直接相談された訳ではないので言ってませんが、メモとして。


この単語が出てきた場合には、
何らかの値が本来は離散値であるにも関わらず、連続値として想定し、連続値用の分布を使って近似する場合で、
ちょっと統計的に有意な差が出ないような側に統計量計算の際、その計算元となる離散値から0.5を減じるという処理を行ってます。
連続性補正 - Wikipedia


メジャーどころではカイ二乗検定イェーツの補正ですね。
この場合には、頻度分布なので離散値なんだけどなー連続値のカイ二乗分布で近似してるよなーという所で、度数の部分で確か0.5減じてたと思います。
位置の検定、順位とか使うやつでも、連続性の補正が発生する事があります。

おまけ

SASでは、NPAR1WAYプロシージャで、PROC NPAR1WAYステートメントでWilcoxonオプションを指定するとWilcoxonスコアというのが計算されますが、単純にVARに指定した順で順位つけてその値を使って計算しています。
「順位」を値としてみなして、それが正規分布だとかt分布だとかに従う事を想定して検定しているだけという、大変簡単な話になってます。
なので、スコアはキレイな数字であり、全体の例数をnとするとn(n+1)/2というのが全スコアの合計になってます。


原義的には正規分布で近似するはずですが、SASではt分布での近似もされる事があります。
この場合、デフォルトではSASは連続性の補正を行っていますが、PROC NPAR1WAYステートメントでCORRECT=NOオプションを指定すると連続性の補正は無しにする事が出来ます。
最近の議論としては連続性の補正ってどうよとかあるかと思いますが、通常は入れとくという話ですね。
ちゃんと指定してくれない依頼者多いと思いますが、最初に「特に指定されていない場合には、SASのデフォルトに従いますよ」的な話つけとくといいかと思います。


なお、このスコアを離散値として正確確率検定を行う事も可能で、EXACTステートメント使う事も出来ます。


Kruskal-Wallis検定は、多群の場合のWilcoxon検定の拡張になります。
正規分布ではなくカイ二乗分布使って検定する訳ですが、
二群の場合には自由度1になるし、Kruskal-Wallis検定の結果とWilcoxon検定の結果(正規分布の方)って一致しますね。

転職しております。

12/1付で某大手電機子会社から、CROの方に転職しました。


リセラーな会社だったので、ライセンスとか使い放題な所があったんですが、次は多分違う。
当面は、SAS Foundation製品触るだけになるだろうなーとは思います。

UTF-8で勘違いしてた事。

wつかないlatin-1領域でも、UTF-8に変換すると非ASCIIの所で2バイトになる。

完全にASCIIなら同じに出来るが、latin-1、wlatin-1なら変換が必要で、

latin-1
最悪二倍
wlatin-1
最悪三倍

だなと。

S-JIS領域での最悪は3倍になる事がある。

半角カナが1バイトから3バイトになるなあ。

US-ASCIIでもlatin-1として変換掛けた方がよい。

何となれば、実際の所、Windowsだったりするとwlatin-1の文字が入力出来てしまう(非ASCII文字を排除しない)。
ブラウザとかでlatin-1指定していてもwlatin-1のイメージで動く。

余談

例えデータセットエンコーディングUTF-8であったとしても、そこに格納されている文字のコードがUTF-8であるという事は全然保証はされてない。
結構どんな言語でもそうで、たまたま上手く変換出来ない文字があったりすると引っかかってくるだけなんだよね。

SASのUTF-8で考える事アレコレ。

簡単ながら。

データセットの内容自体はほぼ対応出来る。

文字の固定長指定を長めにしなければいけないとか色々あるけど、とりあえずは出来る。

問題が残る所がある。

SASのラベルの長さが制限されているが、この為、うっかりすると文字が切れる。日本語で255/3*2=170文字辺り。
ただ、そんなにいるか?というと疑問。「通常は」。

SAS V5 TRANSPORT形式ではヤバい。

SAS V5 TRANSPORT形式(XPORT形式)の場合、古い形式に制限される為、正直困難が有りすぎる。
・文字列長さが200バイトまで
・データセット名が8バイトまで
・変数のラベルが40まで
エンコード情報は持ってくれない
実はこれの拡張のV8形式というのがあるんだが、不思議と流行らない。


何故かというとー、結局文字エンコーディングの情報がないという所があるから。
エンジンもトランスエンコーディングには対応していない。
なお、他の手段ねえかというと、今はXMLエンジン使うという荒業があるが、そんな事するくらいなら案外SASデータセットでいいんじゃないのという話もなきにしもあらず。多分SAS9.3か9.4のシロモノで、あまりテストされてない気もするし、時間かかるよって事だし。

余談

データセットラベルは、元から極力使わない事を推奨しておきます。
プログラムで転がしている最中によく脱落しますし。