The Nameless City

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

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のシロモノで、あまりテストされてない気もするし、時間かかるよって事だし。

余談

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

トランスエンコーディング、というお話を見て。

namelesscity.hatenadiary.com
SASユーザー総会でも誰ぞの発表ありましたが。

エンコーディング情報がないレガシーデータの地獄。

そんなデータあらへんやろーという人に一つだけ言うと。


SAS V6辺りではエンコーディング情報がデータセットにくっついてませんでしたよね?

XPORT形式の地獄。

なので、SAS V5 TRANSPORT FILEの形式だと、トランスエンコーディングの情報がないんですよねー。
SAS 9とかで見ると、エンコーディングがDefaultとか付いてます。Defaultって何ぞやというと、情報がないので現在のセッションのエンコードを無理矢理当てはめますねというくらいにしか意味はないです。

海外データの実際、あれこれ。

SASの世界の話、ですが。

欧米は大体wlatin-1。

だいたいはそうです。UTF-8であってもおおよそはコード値は同じ。
但し、Windowsでの拡張については問題があり、‡とかは位置が異なったりします。
wlatin-1、正確には、Windows-1252といいます。
Windows-1252 - Wikipedia
古来から使われている標準的な仕様としてのlatin-1ではないです。8x、9x辺りが埋まっているのが特徴。
ISO/IEC 8859-1 - Wikipedia
稀にlatin-9とかもあるらしいですが、SASの世界で多いかは知らないです。扱った事はないです。

日本の場合、SJISEUC-JPが混ざる。

Win系のOSだとSJISなのですが、UNIX系ではEUC-JP。
SJIS、正確には、CP932とか言います。
EUC-JPはそのまんまですね。
ただ、SolarisとかはSJISだった記憶があります。本当のレガシーなデータは、つまり結構日本語環境でも文字コード混ざります。

中国語・韓国語は取り扱ってない。

まず、英語版(wlatin-1)で扱われている事が殆どだと思います。

UTF-8を素で使っているケースは稀。

SAS 9.4くらいでも若干UTF-8の表示には弱い所があるみたい、という憶測があります。
SAS 9.1.3では評価版的な機能でUIが追従してませんでしたし、SAS9.2でもUTF-8モードはデフォルトではなかったと思います。
UTF-8モード、ログウィンドウがなんか表示壊れるんですよね・・・・・・

autodetect&transcodingの方法論

発表へのツッコミみたいになるのちょっとイヤですが。

  • 変換表みたいなのを作成し
  • 変換表に従って実行

みたいな二段階にした方がいいかと思うのと、

  • 文字コード変換のバリデーションも自動化した方がいい

です。


自分が実装したのは、「とりあえず○→UTF8変換、そこからUTF-8→○変換」を、想定しているwlatin-1やsjisの分だけ実行して、「実行が異常終了」「proc compareでの比較確認」という感じでやりました。
autodetectのロジックは作るのが面倒でかつ「フォルダ単位でのエンコーディングは普通同一」というような知見を突っ込んだ方が楽だったので。


なお、個人的には、「そろそろHTAヤバいんじゃないかな」とは思うんですが(そろそろWin10)、他、デフォルトで使えそうなのが結局Excel VBAとかだとちょっと悲しいですよね。
けど、Electronとか面倒くさそうだしなあ・・・・・・あの適当さを代替するものって、ナカナカないですよねえ・・・・・

文字コード変換後の実際の長さの検出

最初に、CVPMULT=3とかにしておいて、後で実際の長さに詰める、という事は全然出来るのですが、SASデータセットの場合、油断するとMEMLABELが削れたりFORMATが削れたりするので注意です。SDTMとかはFORMAT要らんですが。
ただ、変換再度あるので面倒だし、COMPRESSオプション使った方が幸せなんじゃないかと思います。

ラベルの変換、変数名やテーブル名の変換

ラベルの最大長が256バイトの為、SJISでダラダラ付けられたラベルは変換すると切れると思った方がいいです。
まあSDTMの場合には変数名やテーブル名の問題も発生しませんが、これ拡張使ってダブルバイトの変数名とか付けてると、これもまた切れます。

独自に作成したアプリケーションのバリデーションはどうするか。

「逆変換して、元のデータセットと比較して確認した」というやり方をした事があります。ただ、結局の所、そのまま申請データとして用いた訳ではなく、多分プロトコル毎にチェックはされているはずです。
そういう形で逃げられない場合にはどうしましょうねえという所は悩みどころ。

プログラムの文字コード変換の場合は、「大変です」。

Windowsでやろうとすると、APIとか叩くプログラム作ったりするのも出来はするんですが。
ただ、逆変換含む比較が難しいというか、「文字として読み込んで、改行文字は適宜CRLFとLFは同じものとして比較」とかありがちなんですよね。
Git適用とか考えておられるならば、改行文字はLFに統一して下さい、とか言いたいんですが、SASのDMSでは改行コードとか指定して保存出来ないかなーと思ったりもします。

立派な客よりマトモな客求む。

もう、あのシステム保守自体切りたいんだけどマジで。


某製薬会社向けの受託開発やったのおそらく十年は前。
システム綺麗にしましょうとかバージョンアップさせましょうとか延々と伸ばされ提案は却下され、保守費用も月数時間とお客さん環境に接続する為のe-Learningやパスワード変更分くらいしかないし。
まあ、それでも理屈にあった事ならまあ仕方ねえなあとは思ってたけど。


出力帳票の全パターン設計に書け、とか言われて正直モチベーションダダ下がりです。
いや、出力に影響するパラメータ複数をわざわざマトリクス化して、「ほらちゃんとそれぞれのパターン網羅してるでしょ」とか書いてたのに、「設計書にはそもそも全て載せるべき」みたいな事を言ってくるんだからもうどうしようもないね。


はあ、ホント何で客のプロジェクトオーナー余所に行っちゃったんだろう。残された人はつらいわ(システム開発してた前任者の先輩は、もう亡くなってるってのもある)。


ある意味、こういう信頼関係の阻害が、システムを遺産化していくんだろうなあとは思うんだよ。ずーっと面倒見てたらそら幾らなんでも「古いXPマシンが必要」とかにはなってねえしなあ。


ああうんざり。


何だろうねえ、名前が通っている会社ほど非人道的な事するし、正直頑張る気がせん。
東京勤務だったらマジで転職してただろうなあ。まあ、大阪でも転職出来なくはないけど、面白味にはかける。


でもなー、データ利活用とか統計だーとかの人って、大体はろくでもないんだよなー。あったら便利程度の道具にしか思ってない。そもそも日本の情報システム部の評価は低いし、コストとしか思ってないからねえ情報システムを。
とにかく安く安く。


AWSだって、「安く」しか見てないでしょ。
そうじゃねえ、「情報システムにはドンドンカネかけてくもんだ」って意識ない。AWSにレガシー如何に載っけるかとか、如何に古いシステムを延命させるかとか、そんなニーズしか日本にはないから、SIerとかの仕事が全般的に腐っていってるだけなんだ。
あまりにも「そんな腐ったユーザを見捨てなかった」業界も悪いんだけどさ。


そろそろ、情報システム側が、三行半突きつけていいと思うんだよねえ。

縛りプレイでの、Phoenix Framework環境構築。

環境の縛り

  • 認証つきProxyで外部環境に繋がる。
    • ユーザIDには「@」を含む。
  • Windows上。

Phoenix Frameworkのインストールガイド

www.phoenixframework.org

必要なアプリ・モジュール

Elixir

そりゃElixirで動くFrameworkだからなあ。

Hex

Erlangのライブラリ管理ツール。

Phoenix

Phoenix Framework本体。Installの所と違ってここに位置付けたのは、単にツリー構造上の話です。Elixirのパッケージだから。
ただ、このインストールの方法では特にHexを使ってインストールしている訳ではない。

Erlang

そりゃElixirはErlangVMで動くからなあ。

Plug, Cowboy, and Ecto

Phoenix Frameworkが必要とするElixirやErlangのパッケージ。中身は今の段階では分からず。
同じVMだからもあるけど、ElixirからErlangのパッケージなんかは利用しやすいようで。
Phoenix入れたら勝手に入るらしい。

node.js (>= 5.0.0)

Phoenix Frameworkではデフォルトではbrunch.ioとかで画面の静的アセット作るらしい。画面はよう分からんが、他に切り替えるほどのノウハウ持っている訳もないので入れておく。

PostgreSQL

裏にDBもつものらしい。うーん、Webアプリから利用するデータおく為のもの?な位置付けでいいのか?
よく知らん。

インストー

Elixirインストー

公式インストーラーで問題なし。
・・・・・・と言いたいがそのままではmixが上手く動かない。後述。

Erlangインストー

問題なし(Elixirと共に入る)。

node.jsインストー

インストール自体は問題ないが、やっぱLinuxベースアプリという事で、Proxyが上手く通らない。
Proxyの設定が必要。

npm -g config set proxy "http://<proxy username>:<proxy password>@<server>:<port>/"
npm -g config set https-proxy "http://<proxy username>:<proxy password>@<server>:<port>/"
npm -g config set registry "http://registry.npmjs.org/"
npm -g config set strict-ssl=false

ユーザ名やパスワードにURIエンコーディングが必要。
試しにbrunch.ioをインストールして通る事は確かめた。
・・・・・・重い。

PostgreSQLインストー

本体は問題なし。psqlodbc入れるStackBuilderが動作しない。Proxy設定を上のように入れてみても上手くいかないので諦め。
psqlodbcを手動で導入した。
postgresユーザのパスワードが、Phoenix Frameworkではpostgresなので苦労しないように一応そうしておく。
・・・・・・良くないです。

Windows版だと、デフォルトでPostgreSQLのそのDB起動周りもサービスとして登録されます。
デフォルトのポート番号は「5432」。

hex導入のmixコマンド

そのままでは動作しない。Proxy設定する所もない。
・・・・・・環境変数http_proxy、https_proxyを設定すればその設定を読んでくれるというのをソースから推測して入れる。
但し、npmの設定と異なり、URIエンコーディングは不要だった。何か他のエスケープ文字あったりする?
他のアプリの設定と一致しないので、ちょっと考えて、mix.batに以下二行を先頭に追加。

@set http_proxy=http://<proxy username>:<proxy password>@<server>:<port>/
@set https_proxy=http://<proxy username>:<proxy password>@<server>:<port>/

これで、「mix local.hex」は成功する。mixコマンド経由ではとりあえずプロキシ通る。

Phoenix導入

「mix archive.install https://github.com/phoenixframework/archives/raw/master/phoenix_new.ez
です。
上が通れば出来るはず。

skeleton試してみる(mix phoenix.new --no-brunch --no-ecto&mix phoenix.server)

プロジェクトの置き場に行って

mix phoenix.new <project name> --no-brunch --no-ecto

する。
すると、のフォルダが出来て、その下にPhoenixのテンプレートがコピーされる。
「Fetch and install dependencies?」と聞かれてYを選択すると、その後に、mix deps.getが実行されて、依存関係のあるモジュールも落ちてくる。

cd <project name>
mix phoenix.server

で、フォルダ配下のElixirのファイルがコンパイルされて、サーバが動く。

普通にプロジェクト作ってみる(mix phoenix.new)

プロジェクトの置き場に行って

mix phoenix.new <project name> --no-brunch --no-ecto

する。
Phoenixのテンプレートがコピーされるまでは一緒(但しモジュールが増えてる)。
ただ、先の質問でYを答えると、mix deps.getの後に、

npm install && node node_modules/brunch/bin/brunch build

が実施されている。これが遅い。

これで、package.jsonの内容をインストールしているらしい。
んだが、クソ重い。なんだこれ。
まあ、他にCPU使ってるのもあるんだけど・・・・・・

多分、前のDISのは、当面直らないんではと思う。

namelesscity.hatenadiary.com
あれからも、このバグって簡単かねえと思いながら見てたのですが、
そういや、
Oracleの場合二重引用符で列名を指定する事が出来た
なと。
SASは名前リテラル('~'n)というのを持っているので二重引用符と一重引用符の使い分けなしに(この使い分けは、SASはマクロ言語の所で使ってしまっている)なんとかなりますが、SQLとして標準化されていくものとしてこんなの使われる訳ないよねと。


PROC SQLステートメントのオプションに、DQUOTE=オプションがあり、ANSISASどちらかで指定出来るのですが、ANSIで設定すると二重引用符で列名を記載する事が出来ます。SASの場合には、これは文字リテラルであるなと認識されます。
つまり、そういう細かいオプションに判定アルゴリズムが引きずられるので、多分問題になるかと思います。
PROC SQLも古いプログラムですしね。SAS/ACCESS Interfaceあたりにも影響するはずの為、ちょっと簡単ではないと思われます。


なお、FEDSQLというのが出てますが、イマイチ使い勝手は分かっていません。

意外と知られていない、データセットの指定方法。

ネタ用のソース。

手持ちのSASで試して見て下さい。
しかし、SAS On Demandの場合にはこれで動くかはやってないので正確な所は分かりませんが多分出来ないです。SAS University Editionも同様で、SAS Integration Technology上に乗っかってるのでは、XCMDが無効化されているので、データ作成とかCDとかが多分無理。
(XCMD/NOXWAIT/XSYNCが望ましいです)
WORKライブラリの配下であればフォルダもありますが、他、システムオプションが権限コントロールされているので無理かなとも思います。

** 下のテスト用のフォルダは、自分の環境に合わせて適宜変更して下さい ** ;
%let _FLD=C:\Workspace\tmp ;
%let _DR=C: ;
/*
念の為。
Windows環境下では、UNCパスでは最後のCDコマンドが動かないので注意
*/

** テストデータ一次作成 ** ;
libname TEST base "&_FLD." ;


data  TEST.CLASS ;
	set SASHELP.CLASS ;
	attrib MEMO length=$20. ;
	retain MEMO ;
	if _N_ = 1 then MEMO='demo用データ' ;
run ;

** このライブラリ設定がクリアされていない場合には、そのライブラリを使いにいく ** ;
libname TEST clear ;

title '**フルパス指定**' ;
title2 '**こんな指定の仕方で大丈夫か**' ;
footnote '**問題ない**' ;
proc print data="&_FLD.\class.sas7bdat" ;
quit ;

footnote ;


title '**定義情報**' ;
proc contents data="&_FLD.\class.sas7bdat" varnum out=_wk_def;
quit ;

title '**定義情報** ライブラリが自動設定されている...WC<連番>という形で定義される' ;

proc print data=_wk_def ;
quit ;

title '**ライブラリ定義(SAS...以外)...WC<連番>という形で定義される**' ;
proc print data=SASHELP.VLIBNAM ;
	where LIBNAME not like 'SAS%' and LIBNAME not like 'MAP%' and LIBNAME ^= 'WORK' ;
quit ;

** 自動割当されたライブラリを一旦クリアしておく ** ;
%let _w_lib = ;
proc sql noprint ;
	select LIBNAME into : _w_lib from SASHELP.VLIBNAM
	where LIBNAME not like 'SAS%' and LIBNAME not like 'MAP%' and LIBNAME ^= 'WORK' ; 
quit ;

data _null_ ;
	attrib LIB length=$10. ;
	LIB = symget('_w_lib') ;
	if not missing(LIB) then do ;
		call execute(catx(' ','libname', LIB,'clear ;')) ;
	end ;
run ;


**もしかしてこれファイル名変なのにしても大丈夫?** ;
title '**EXTEND指定の場合のSASデータセット名制限の緩和**' ;
option validmemname=extend ;


data "&_FLD.\1_class.sas7bdat" ;
	set "&_FLD.\class.sas7bdat" ;
run ;


title2 '**こんな指定の仕方で大丈夫か**' ;
footnote '**問題ない**' ;
proc print data="&_FLD.\1_class.sas7bdat" ;
quit ;
footnote ;


**名前リテラルを使うパターン** ;
title '**名前リテラル指定**' ;
libname TEST base "&_FLD." ;

title2 '**こんな指定の仕方で大丈夫か**' ;
footnote '**問題ない**' ;
proc print data=TEST.'1_CLASS'n ;
quit ;
footnote ;


**実はこんな酷い事がwww** ;
options xsync ;
x "cd ""&_FLD.""" ;
x "&_DR." ;
/*
念の為。cd /d ...のコマンドはSASは理解しない為、
/d つけると失敗します。
*/
title '**相対パス指定**' ;
title2 '**こんな指定の仕方で大丈夫か**' ;
footnote '**問題ない**' ;
proc print data='1_class.sas7bdat' ;
quit ;

データセットの指定方法の簡単な説明。

普通のやり方。

「<ライブラリ名>.<データセット名>」ですよね。
因みに、ライブラリ名を省略した、「<データセット名>」の場合、WORKライブラリ配下に作成される

のが普通なのですが、実はUSERシステムオプションに従う事になってます。そのデフォルトがWORKです。
ただ、このオプション、キリキリ切り替える人ってそういないと思います。設計時点で仕込めば問題ないんですが。
そういう言語仕様なので、SASのソリューションで自動生成されるプログラムではまずライブラリ名は省略されてないと思います。

パス指定。

引用符で囲む事によって、「パス指定でデータセットとして認識させられる」んです。


これ、面倒臭いだけじゃんとか思われるかとも思いますが、ライブラリ設定をしなくても済むってのが利点で、勝手にBASEエンジンのライブラリが定義されてその下に出来ているように見えます。


ただ、この仕様ちょっと厄介で面白い所もあります。
'c:\workspace\tmp\class'で指定→「c:\workspace\tmp\class.sas7bdat」で作成。
'c:\workspace\tmp\class.dat'で指定→有効ではない拡張子が指定されているとしてエラー。


つまり、パス指定と言えども、実際には「ライブラリの自動登録と、データセット名の推論」で動いているかと思われます。
これ、

data CLASS ;
    set SASHELP.CLASS ;
run ;
data 'CLASS' ;
    set SASHELP.CLASS ;
run ;

どちらでも大抵はclass.sas7bdatファイルが出来るのです。
「ライブラリが省略された場合に補完される」のは通常「WORKライブラリ」なので、そこに出来るのですが、
相対パス指定」の場合には通常SAS起動時に設定されている作業フォルダ(カレントディレクトリ)なので、素のSAS起動直後では「%userprofile%」(C:\Users\)に出来ます。

SASの各種ツールはSAS構文全てに対応している訳ではない、例としてのDISの変な挙動の話。

DISのマッピングで出てる警告について聞かれたのですが。


DISにはDISに食わせる為の書き方というのがあって、例えソースが一種類であっても、「テーブル.列名」という記述をする必要があったんじゃないかと記憶しているのです。
面倒臭いなと思ったら生SASを書いてしまう人なので、実はあんまりDISのTransform(SASの日本語マニュアルで「変換」って書かれますけど、これ用語として良くないですよねー)を使わないのですが、DISのTransformでどこまで警告消せるかっての試してた事がありまして、その経験値になります。
DISのTransformって、結構マニアックな所までGUIで出来てしまうんですが(サブクエリも書けます)、画面のオブジェクトをクリックした中に入れ子を作っていくのは結構問題あるなーと思って、出来るだけJOINでなんとかする書き方を考えたり、色々悩む事はあります。


話戻しまして、SASのエンジンが理解出来る構文が、その実ラッパーであるDISが理解出来るかというとこれが案外理解できず困るという事は多々あります。
また、データの持ち方として、「列とはテーブルを親に保つもの」というオブジェクトが想定されているのもあるでしょう。多分。
余談ながら、式ビルダもホントイケてないから問題なんですよねえ。
Transformも複雑なものだと案外「こういう使い方するもの」ってのは、想定と違ったりするので。
自分でやる際には、殆ど生SASSQL結合使いかですねえ。


うんまあ、SQLでビュー作ったの繋いでいくよりも、生SASでビュー繋いでいく方が正直早い気がするんですよね。


ダラダラと前フリしましたが、以下、まあこういう事があるよという例です。
ちなみに、これが発生するのは、SAS DIS4.901で確認しております。

f:id:houyhnhm:20170516170009p:plain
はい、この原因は、多分文字リテラルと変数名が被っちゃっててなんだろうと思います。
因みに、データは、SASHELP.CLASSからの流用です。
f:id:houyhnhm:20170516170026p:plain
実行すると警告は出ますが、
f:id:houyhnhm:20170516170036p:plain
データについては特に問題はないです。マッピングの紐付けのメタデータがイマイチイケてないだけです。
f:id:houyhnhm:20170516170102p:plain
人力で「テーブル名.」を補完してやります。
f:id:houyhnhm:20170516170116p:plain
補完した文字は消えますが、警告マークが取れます。
f:id:houyhnhm:20170516170131p:plain
実行しても警告は出ないようになりました。


単純にDISのマッピング判定のロジックがイケてないって事だと思いますが。
直らん上に結局仕様(警告マーク無視して)とか言われかねないので、まあ下策ですがこんな形でこのジョブ上のTransformの中身を作ってやる、と。
これ出来ないと、開発系から本番系へのお引っ越しなんかの時に、テーブルの紐付けどうやって確認したらいいんだという話になりかねないので(警告マークが信用出来なくなるから簡単でなくなる)こういう対応もありかなという所です。
所詮はプログラムのエディタだと割り切った方が良いです。


一応似たようなケースでのエラーでProbrem Noteは出ていて、その中では「Warning抑止するオプションを設定」でした。
52167 - A warning occurs on the Mapping tab when you join a table with itself via aliases in SAS® Data Integration Studio
うんまあ酷いな。
今のDISでも出てますが、警告ない状況でセーブして再度開くと警告になるという、大変タチの悪い状況です。ただ、同一テーブルをソースにしてのJOINとかはまずやらんと思いますが。
報告されてるエラーの回避策として、「どちらか一個にTransformかますと大丈夫」だったりします。要は同名テーブルだがエイリアス設定があるみたいなのが上手くいってない所なので、ビューとして別物に仕立てると大丈夫だったり。
同様にして、「変数名を変えておく」のが一番マシな回避策かも知れない。

余談

SASのバージョンによって挙動が変わったりする所があるかと思います。ご注意下さい。
特にこの辺りSASの正式ドキュメントはないので申し訳ないですが表立って回答として出せない為、無責任な状況でご提示しておくものです。
なんとなく察して下さいお願いします。
お引っ越しに関しても大丈夫かどうか確認してませんのでよろしくお願いします。

COMPRESS=オプションの活用。

実は、V6時代から存在するけど、その実あまり使われていないような気がするオプションですが、
パフォーマンス等にメチャクチャ影響するので、適度に使う事を推奨したいオプションです。
個人的にはCOMPRESS=YESってデフォルトでもいいと思うんですけどね。

使い方幾つか。

個々のデータセットに使う方法。

data CLASS(compress=yes) ;
    set SASHELP.CLASS ;
run ;

こんな感じです。この場合には、全く圧縮率は上がりませんが。

ライブラリに定義しておく方法。

libname TEST base "C:\test" compress=yes ;

こちらは、「今後TESTライブラリ配下に作成される際に参照され」、ライブラリ配下のデータセットが圧縮して作られます。
COPYプロシージャなどでコピーする際には原則として適用されないと思った方がいいです(多分オプション駆使したらいいんだろうけど)。

システムに定義しておく方法。

options compress=yes ;

このステートメントが実行された後、「全てのBASEエンジンでのデータセットを作成される際に参照され」、圧縮して作られます。
但し、基本的にはセッション毎に保持されるものと思って下さい。sasv9.cfgなどで設定ファイルに設定した場合には、全てのセッションに反映されます。
SAS実行用のサーバを構成している場合には、Workspaceサーバ等だけに適用する方法、SASApp配下全体に適用する方法などで設定ファイルを弄る事を推奨します。Metadataサーバに適用してしまっても多分意味がない・下手するとパフォーマンスちょっと悪化するので。

圧縮のロジック・影響

個々の変数に対して連長圧縮という事をします。
その為、適用されても必ずサイズが小さくなる訳ではありません。
連長圧縮 - Wikipedia
圧縮効率は悪いですが、極めて単純なロジックの為、CPU負荷はあまりありません。ディスクI/O待ちがかなり多いSASの場合にはかなり有利なロジックではあります。


以下イメージ。
CSVファイル

abcdefghi,,abcdefghi,
,abcdefghi,,

SASデータセットイメージ(定義の部分とかで大きめなヘッダがついてますが、大体イメージです)

abcdefghi,_________,abcdefghi,_________
_________,abcdefghi,_________,_________

SASは、固定長文字列としてデータを保持する為、COMPRESSオプション指定なし、デフォルトのNOである状況では、定義の長さまでデータを半角スペース(0x20)で埋めます。
定義の長さまでデータが埋められてない、欠損値が多い(SASではRDBのNULLのようなものを欠損値と表現します。厳密にはRDBのNULLとは異なり、型としては数値型・文字型両方あります)場合には、この「ただ埋める為だけの半角スペースが多い」ので問題になります。
このせいでCSVのサイズとSASデータセットのサイズも比例しづらいです。

余談

SASの固定長文字列型というのは、これ今後も変わらないと思います。
2000年代でも既に珍品の域だったと思いますが、ただ、どんなプラットフォームでもそこそこ高速に動くのはこの辺りの仕様です。
メモリ消費量が案外小さいのもそうで、ただ、プロセス起動が重い(イチイチフォルダ作って物理実体を作業スペースでも作ってしまう)のも問題ではあるんですが。
プロセス起動のネックになっているWORKライブラリは、MEMLIB等の設定がありますので、高速化考えているならば検討の余地はあります・・・・・・が、結局の所、SSDより大容量なメモリを抱えている訳でもないので・・・・・・パフォーマンスチューニングは厄介ですねえ。
固定長文字列型というのの利点は、ディスクのページサイズと合わせる事によって、変なディスクキャッシュをかまさなくて高速に動く所、ですかね。

余談:SAS EGでのやり方

データインポートのタスクにデータセットオプションを指定する方法はどうも簡単にはなさそうなので、システムオプションを変更するプログラムを作り、上記タスクの前に実行するようにフローを作った後、まとめて実行する方法が良さそうです。
注意として、一度システムオプションで変更するとセッション中はずーっと圧縮かけるように設定されてしまう為、必要があれば解除するようシステムオプションを再度設定しなおすという事も行って下さい。
ただ、一点ツッコミ入れておきますが、データインポートでは、EGからサーバへ平文のCSVが転送されます。その手の変換はサーバ内でDISや生SAS使うのが妥当です。

レガシーシステムの規制当局申請用データ変換の不毛さ。

時代遅れでかつデザインもイケてないフロントを何故ひたすら抱えさせるのか意味不明であるし、
データ移行を楽にする為なのか、内部構造ももう消費期限過ぎているのに無理矢理延命させる意味も分からん。
オマケに、元々の内部構造が、正規化されてないので拡張にイチイチalter tableする必要があるって頭が悪いとしか思えない。


そもそも、データの履歴含めて保持する必要があるシステムのはずが、そこの時点でリファクタリングや作り直しをやれてない時点で、開発当初から失敗するのが目に見えてる。
それに気付かず計画を進めるような人材が大量にいる時点で終わってるのだけど、何故そのグタグタなものをシステムで作り上げようとするのか意味不明である。


お前らいい加減Part11理解しようよ。データのトレーサビリティ要求されんの近年の重めなシステムでは当たり前でしょうが。
チョロチョロっとデータ加工して弄る、みたいな事しても仕方ねえんだよ。
もうお前ら馬鹿なんじゃないかと繰り返し怒鳴りたくなる。


そんなパッケージでもそれなりの売上が出てしまう所が、大手SIerの問題だろうなあ。
文句言わなければそこに寄生して食ってける。


ああ、いい加減綺麗な新規開発したい。現在販売中のパッケージだって、これ、中身は二十年前とか余裕な時代遅れのシステムで、完全に技術的負債になってるのに偉いさんは金の卵のように扱うんだ。
ホントうんざりする。

SASのライセンスの上手い使い方、というのが大変むずかしいっぽい。

SASが高い、というお悩みは昔からよく見かけてたんですけど(英語圏で)、相変わらずそこは悩みどころのようです。
ただ、日本の場合、特にライセンスの費用を抑える為に、SASの極めて狭い機能で利用しようと試みて、変な所で悩んでいるような気がします。


SASの会社としては、「○○を入り口に」もっと各ソリューション製品で業務を回してほしいという思いがあるのですが、旧来よりのSASユーザはあんまり業務分野を広げる事に積極的ではない事も多く、また、多くのフリーソフトを活用してローカルかつミニマムなシステムを作る事が多いようです。
OSSではあまりないです。ベクターなどからダウンロードしたフリーのツールみたいなもので作ってる感じです。


ユーザに近いプログラマーは、極めて原始的なスタンドアロンツールを開発する事が多く、海外のように社内でサッサと環境を作る事ナシにExcelファイルで展開というような形が大変多いです。
その為、素のSASの開発プラットフォームを導入しても大した効果が出ません。
ここらへんが悲しい所で、目の前の開発基盤を眺めながら素のSASプログラム書いてたりするって感じなんですよね。
その為、全然ソリューション製品への導入になってません。


日本の場合、ソリューション製品というのは、おそろしく面倒臭い導入工程を経るというのが一般的になってしまってますが、
もう少しエンドユーザに権限を持たせて、自由度上げてあげたらいいのにとは思います。
・・・・・・システム作るの面白いですよ。


でですね、SASのライセンスはそういう文化の違いを認識していない組み合わせなので、どうしても「ある機能しか使わない」という事には弱いんですよ。
サービスメニューもその辺り損をしてます。サービスで何かのライセンス付けても全然使われないんだって。社内にプライベートクラウド作っても、ユーザが自由に試せるサンドボックスではないんです。社内でAWSみたいなセコセコした金払いが発生し、それを上長が予算化しておいて初めて使えるけど、その予算化にはしっかりした説明が必要で、と、かなり悲しい話になります。


この辺り、もう少し詰めて話せればいいんだけどなあ・・・・・・
まあ、大体手遅れの段階で質問されるのよね。

SASデータセットでストレージが圧迫されて困る人へのTips。もう少し深めに。

「○○ではサイズがちょっとだったのに、SASデータセットにすると大きくなる」というのは、あるあるなので。
その予断を地上から消し去りたい。
SASデータセットでストレージが圧迫されて困る人へのTips - The Nameless City

SASの固定長文字列型という所が悪さする事がある。

固定長文字列型の長さとしては1~32767バイトまで定義出来る。他システムで長さを定義しなくていい可変長文字列型のデータをSASに取り込む際には32767バイトに拡張される事がある。

大体はIMPORTプロシージャの設定を見直してほしい。

Technical Support:IMPORTプロシジャでCSVファイルを読み込む際の文字切れを回避する
http://www.sas.com/offices/asiapacific/japan/service/help/pdf/v94/proc.pdf
テキストファイルのインポートの場合に、私はIMPORTプロシージャをまず使わないが。
余談だが、

文字列型で本当に保存するべき項目か考えてほしい。

SASの数値型は倍精度浮動小数点型であり、整数型がないので不安になる事もあるだろうが、有効桁数としては十進数でおおよそ15桁ある。
最悪、二つの変数に分割したとしても、文字型で持つよりは圧倒的に小さい。
また、カーディナル値が低い文字型の変数の場合には、おおよそ分類用の変数なのだから、SASフォーマットを利用する事を考えてほしい。
内部的には数値あるいは文字でコード値を持ち出力時にはラベルを出力する、という事が簡単に出来る(統計プロシージャでも対応している)。
このSASフォーマット、サーバで利用している場合にはちょっと対応が難しい(GUIが認識するように設定するのが結構面倒臭くてまたそれ用のフォルダが固定でサーバで一つなので利用しづらい)が、他の場合には、RDBMSと同様にマスタテーブルを作る事でだいぶマシになる。


SDTMのTerminologyがなんでコード値持って格納するような形式になっていないのかは、正直謎なんだが、コードのテーブルがガンガン変更されると悲惨だから、なのかねえ。でも無駄だと思うんだけど。
そもそもSAS V5のxport形式にする意味がわからんよなあ・・・・・・

ちょっとずつレコードを処理して「試して」から実行してほしい。

特にSASサービスを立てている場合。途中で変なキャンセルとか効かないので。
レコード数を絞るオプションとか色々あるやん?

正規化されたテーブルからビューを作って実行する事を考えてほしい。

SASのデータステップはビューとして置く事が出来る。無論SQLもビューにする事は出来るんだが。

データの根本の所から絞り込みしてほしい。

SAS/ACCESS~の製品は、各製品と連携して絞込や簡単な集計とかは、データベースなどに実行させてSASから取得する事が出来る。
データの移送量を減らすとかなり快適だと思うんだがなあ。

集約すると。

もう少し設計の観点を持って頂くと大変助かる。

SASのライセンスのお話について少し。

ライセンス更新等にまつわる話。

大前提として。
「ライセンスの有効期間中は使えます。ライセンスの有効期間が終わると使えません」ってのがソフトウェアのライセンスなんですってば。
一応、SASでは、「既に入れている場合に関しては、猶予期間・警告期間のフェーズを設けて、イキナリ業務の問題に発展する事はないようにしています」。が、所詮ソフトウェアのログに吐かれるだけなんで、よく見落とされてます。
経験上は、だいたいは一年契約で猶予期間・警告期間それぞれ30日程度の期間があります。但し、評価版の場合には、猶予期間0日、警告期間5日とかありますね。

  • 使用期限
    • ライセンスが切れる日。余談ですが、開始日の設定はありません。
  • 猶予期間
    • 使用期限の後(ライセンス失効後)、ログに警告も出されない状況で使用は出来る期間。日数で設定されてます。SAS Deployment Wizardによるインストールは出来ません。
    • 新規インストールはギリギリやれるとの事ですが。
  • 警告期間
    • 猶予期間後、ログにライセンス切れの警告が表示される期間。日数で設定されてます。この時になって慌てる人がいますが、この時既に契約について動いていないと日本の会社の場合ギリギリになる事が多いです。


繰り返しになりますが、使用期限の時点でライセンスが切れている為、大抵のサポートは受け付けられませんからね。
49516 - Frequently asked questions about SAS® 9.4 software

大学向けライセンスの話。

学校向けのライセンスは、昔よりだいぶ安くなってます。
が、日本の大学ではなぜか研究室単位で個別に買うのがよくあって、結果的に高くなってる事がよくあります。
あと、各部署の予算とか範囲争い、入札要件の無駄にオープンな仕様のせいで、高い買い方をしている事があります。
無駄に古臭い使い方が想定されてたり。てか、SASの新技術とか日本でついていけてる大学人は多分ごく少数しかおらん。


以下愚痴。
「え、X11経由で使うのか」
SAS DMS使うならLinuxのプログラムエディタは使いづらいんだよね。デフォルトでは書いた文字が消えるし」
「しかし、SASデータセットが簡単に参照出来るのは捨てがたい」
「でも、文字コードが面倒なんだよね。LinuxだとEUC-JPがデフォルトだし、UTF-8も対応してないって出るし」
「そろそろSAS Studioでやってほしい。SAS DMSは化石。」
「でも余計についているSAS Content Serverがデータバカバカ入れられそうでつらそうなんだよなあ。中でVMWare vFavric TC-Serverが使われてるし、セキュリティ的に気にする所が増えるし」
「その手の要件詰めてくれなさそうだしねえ」


CENTOSでもインストールは出来るけどね」
「一部RHELの話をCentOSとして読み替える必要がPerformance Tuningあたりで出てくるんだけど、試ししかやってないしなあ」
「そもそもSASが正式にサポートしている訳ではないんだよなあ代替OS」
「個人的には、CENTOSGUIGNOMEとかIMEAnthyもMozcも使えないのがストレス」
Debian系統にはインストール出来ないんだよねえ。SAS University EditionはどのOSでも入るけどVMで突っ込ませてるだけだし」

ViyaもVAも日本では刺さりにくい。

エンドユーザに近い製品にしては、やたらと真面目に表の構造を理解しないといけないという事もあって、この製品は難しいなと思っている。
また、若干統計家も触りやすいであろうViyaについても、これに金を出してもらえるかというと微妙。


というか、まあ、データサイエンティストがイマイチ育つ土壌ではないんだよねえ。
機械学習が使えるとか、いやうんちょい待った方がいいのかも知れない。


GUIでも裏でコードが生成されるしかなり便利なツール、を目指しているSASと大変相性が悪いのが日本のような気がするなあ。
ちょっと前にVAのお客さんの端末でブラウザがメモリエラー吐いていて、「これは厳しいな」と思った記憶がある。
日本ネットワークは結構工夫されてんだけど、個人端末が貧相なんだよなあ。

SAS9.4TS1M4のリリースの案内が今日来るってどういうことなの。

この度、11月22日(米国時間)にSAS 9.4 M4(16w48)が出荷開始となりましたのでお知らせ致します。

メールくれないよりはマシだけどさ。
英語サイトの方では先週にだいぶ対応されているんだけど、何故日本は遅れるのか意味が分からない。
AMOの自動更新機能で気付くようになってるので、もう少し努力しましょうというか本国とちゃんと連携しないと厳しいよホント。
しかももうそのHotfixが出てる状況なんで。