SAS Intelligence Platformのインストール周りからの説明作り。
もういい加減説明するのも疲れた・・・・・・
タイトル通り。
いわゆるISO-8859-1、通称Latin-1というヤツであるが、これ、Windows上では拡張されWindows-1252というものになっている。
この拡張された部分に埋められた文字が、UTF-8では3バイトになるものがある。ダガーやダブルダガーとか。
shift_JISからだと、2バイト→最大4バイトでありcvpmultは2で十分なのだが、wlatin-1だとこれがcvpmult=3を設定しなければいけない。
大変残念である。
本来はlatin-1はUTF-8でも文字としてのバイトの中身が変わらんのだけど。大変残念である。
追加:latin-1かつ非ASCIIの場合には、UTF-8と解釈しようとしても上手くいかない。
IBM Windows のファイル名の文字コードについて - Japan
があったので、大変有り難い。
ほぼそれの内容なのだけど。
いわゆるUTF-16LEでNTFSでは登録されているのだが、ファイルシステムが違う場合、特にFATとかでは日本標準ではS-JISに変換されるよう。
で、このファイルパスがUTF-16LEであるのにも関わらず、各アプリケーションではS-JISとして使われる。
(5) Windows 上で稼動するアプリケーションには、Windows カーネルが SJIS に変換して渡す
IBM Windows のファイル名の文字コードについて - Japan
これは、必ずという訳ではなく、APIを経由すれば呼び出しも可能のようなのだけど、Windowsの幾つかのものがそもそもそういうのにマトモに対応していない。
多くの人が、「インストーラーに従ってインストールすれば問題ないよね?」的な発想でインストールされると思います。
特に問題がなければそれでだいたいは大丈夫です。間違ってません。
ただ、たまーに問題が発生するのですが、そこら辺を自力解決というには、ちとインストーラーも含めて親切になり過ぎてます。
まあ、滅多に発生はしないのですが、発生すると「ああ、そういや昔からこんなトラブルあったなあ」と古い人は懐かしく思うんじゃないでしょうか。
SASは英語圏、頑張ってもLatin-1のあんまり拡張使わない領域で構築されてます。
それ故に、英語圏パッケージでありがちな間違いをよくしています。
そこら辺のトラブルを避けるなら、まずその辺りを考慮し、ダブルバイト文字をとにかく混入させないようにしてください。
また、インストール前の処置は重要です。アンチウィルスソフト停止、はまだいいんですけど、それからSASをデータ実行防止の例外に登録しておくことも必要です。
インストールの後処理で、sasv9.cfg周りの設定をやっているように思うのですが、その際にコケる事があります。
今、Windows8.1ではoutlookアカウントに紐付ける形でアカウントを最初に作る事が多々あり、そのアカウント(管理者権限持ち)でインストールすると、SASバッチで何かしている時にコケてるようです。
Windowsの場合には、大概Administratorが使えるのでそれで実行するのが最善ですが、そうでない場合には、インストール用の英文字だけで構成されたユーザを作成してインストールして下さい。
よく画面眺めていると、データ実行防止機能でsas.exeを止めたと、タスクトレイにポップアップで表示されます。
これは、64bit版SASではなく32bit版SAS限定で発生します。イベントログにはたいていOffice IMEに対してsas.exeが不正アクセスっぽい事してると警告が上がります。
データ実行防止機能の例外に登録してください。
レポートにsastestのプログラムが出ているので、それをデフォルトで起動するSAS DMS上で再実行して見て下さい。多分たいていはSASの日本語版が起動すると思います。
proc compareで間抜けにも、日本語の文字と英語の文字を比較している結果が表示されてるかと思います。原因はそれです。
たいていは、アンチウィルスソフトが悪さをしています。インストール中には実行を停止してみて下さい。
Analytics Proでトータル三時間もあればインストール出来るのですが、これを知らなくて辛抱強く待つ人もいます。出来なくもないですが、びっくりするぐらい時間がかかるのでこちら推奨です。
まあ、タイトル通りですが。
他人の能力というのは過信してはならず、予定通りに進んでなさげな場合には、マイルストーンを適切に作らせるとか、そういう事をしていかなければならない、という気がします。
ちなみに、定型的にミスが発生する場合には、チェックリストなどを作成してもらい、それに従ったチェックをさせるとか、そういう事をしていかないと、レビューアーが増えません。
まあありがちといえばありがちなんですが、社会人の心得とか意識とかに任せるといつまでもそこら辺に忙殺されるので、体系化してフローに組み込んでしまうというのがいいですねん。
b.hatena.ne.jp
で、ブコメでもちょっとコメントしてますが。
まあ、A/Bでそれぞれn=10000みたいな状況の場合には、統計手法の選択もクソもなく、ほぼほぼ元々の母集団での比率に差があればpは0に近くなります。
計算するだけ時間の無駄です。比率出して比較すればいいだけです。
ちなみに、SASのコードで書くとこんな感じですが。
data test ; attrib pattern length=$1. ; attrib cv length=8 ; attrib imp length=8 ; input pattern cv imp ; cards ; a 30097 100399 b 28901 99896 ; run ; data test2 ; set test ; attrib event length=$4. ; attrib uu length=8 ; event = 'cv' ; uu = cv ; output ; event = 'miss' ; uu = imp-cv ; output ; run ; proc freq data=test2 ; table pattern * event /cmh ; weight uu ; quit ;
FREQ プロシジャ 表 : pattern * event pattern event 度数 | パーセント | 行のパーセント| 列のパーセント|cv |miss | 合計 --------------+--------+--------+ a | 30097 | 70302 | 100399 | 15.03 | 35.10 | 50.13 | 29.98 | 70.02 | | 51.01 | 49.75 | --------------+--------+--------+ b | 28901 | 70995 | 99896 | 14.43 | 35.45 | 49.87 | 28.93 | 71.07 | | 48.99 | 50.25 | --------------+--------+--------+ 合計 58998 141297 200295 29.46 70.54 100.00 pattern * event の要約統計量 Cochran-Mantel-Haenszel 統計量 (テーブルスコアに基づく) 統計量 対立仮説 自由度 値 p 値 ---------------------------------------------------------------- 1 相関統計量 1 26.3809 <.0001 2 ANOVA 統計量 1 26.3809 <.0001 3 一般関連統計量 1 26.3809 <.0001 共通オッズ比と相対リスク 統計量 手法 値 95% 信頼限界 ------------------------------------------------------------------------------ オッズ比 Mantel-Haenszel 1.0516 1.0316 1.0721 ロジット 1.0516 1.0316 1.0721 相対リスク (列 1) Mantel-Haenszel 1.0362 1.0222 1.0503 ロジット 1.0362 1.0222 1.0503 相対リスク (列 2) Mantel-Haenszel 0.9853 0.9797 0.9909 ロジット 0.9853 0.9797 0.9909 標本サイズの合計 = 200295
このモデルをそのまんま使って、ただし、
a 30097 100399
b 28901 99896
を
a 30 100
b 29 100
a 300 1004
b 289 999
で同じように検定してみましょう。
(見ればわかると思いますが、サンプルサイズを元の千分の一、百分の一という感じにしてます)
FREQ プロシジャ 表 : pattern * event pattern event 度数 | パーセント | 行のパーセント| 列のパーセント|cv |miss | 合計 --------------+--------+--------+ a | 30 | 70 | 100 | 15.00 | 35.00 | 50.00 | 30.00 | 70.00 | | 50.85 | 49.65 | --------------+--------+--------+ b | 29 | 71 | 100 | 14.50 | 35.50 | 50.00 | 29.00 | 71.00 | | 49.15 | 50.35 | --------------+--------+--------+ 合計 59 141 200 29.50 70.50 100.00 pattern * event の要約統計量 Cochran-Mantel-Haenszel 統計量 (テーブルスコアに基づく) 統計量 対立仮説 自由度 値 p 値 ---------------------------------------------------------------- 1 相関統計量 1 0.0239 0.8771 2 ANOVA 統計量 1 0.0239 0.8771 3 一般関連統計量 1 0.0239 0.8771 共通オッズ比と相対リスク 統計量 手法 値 95% 信頼限界 ------------------------------------------------------------------------------ オッズ比 Mantel-Haenszel 1.0493 0.5713 1.9270 ロジット 1.0493 0.5713 1.9270 相対リスク (列 1) Mantel-Haenszel 1.0345 0.6739 1.5880 ロジット 1.0345 0.6739 1.5880 相対リスク (列 2) Mantel-Haenszel 0.9859 0.8241 1.1795 ロジット 0.9859 0.8241 1.1795 標本サイズの合計 = 200
FREQ プロシジャ 表 : pattern * event pattern event 度数 | パーセント | 行のパーセント| 列のパーセント|cv |miss | 合計 --------------+--------+--------+ a | 300 | 704 | 1004 | 14.98 | 35.15 | 50.12 | 29.88 | 70.12 | | 50.93 | 49.79 | --------------+--------+--------+ b | 289 | 710 | 999 | 14.43 | 35.45 | 49.88 | 28.93 | 71.07 | | 49.07 | 50.21 | --------------+--------+--------+ 合計 589 1414 2003 29.41 70.59 100.00 pattern * event の要約統計量 Cochran-Mantel-Haenszel 統計量 (テーブルスコアに基づく) 統計量 対立仮説 自由度 値 p 値 ---------------------------------------------------------------- 1 相関統計量 1 0.2183 0.6403 2 ANOVA 統計量 1 0.2183 0.6403 3 一般関連統計量 1 0.2183 0.6403 共通オッズ比と相対リスク 統計量 手法 値 95% 信頼限界 ------------------------------------------------------------------------------ オッズ比 Mantel-Haenszel 1.0469 0.8638 1.2688 ロジット 1.0469 0.8638 1.2688 相対リスク (列 1) Mantel-Haenszel 1.0329 0.9018 1.1831 ロジット 1.0329 0.9018 1.1831 相対リスク (列 2) Mantel-Haenszel 0.9866 0.9324 1.0440 ロジット 0.9866 0.9324 1.0440 標本サイズの合計 = 2003
という感じで、「同傾向のデータでも増やすとより有意を見つけやすくなります」。
元の話に戻って考えてみればいいのですが、
というぐらいな話なのです。
この3万/10万と2万9千/10万で表されるような「サンプルでの比率」は「母集団の比率の推定値」になるわけなんですが、そうした時に「母集団でも確かにこの比率の差が発生する」という事を仮説として考え、その対立仮説「母集団ではこの比率の差がない」の確率を求めているというのがこのp値です。
まあ、例えば「想定される母集団が例えば10万人程度だったら」、ほぼ全例調査なわけで、そりゃその1千人の差は確かでしょうし、
だと、先ほどの話よりもサンプルが偶然そうなってただけの可能性があるわけです。
そもそもこんな例数で検定かけるとかwというものです。
"2-sample test for equality of proportions with continuity correction" は 2 郡の比率が等しいかどうかを検定したことを意味しています。その際、連続性の補正 (continuity correction) を行った旨が表示されていますが、連続性の補正の有無で経営判断が変わるほど結果に影響を及ぼすことはまずないと思われるので気にしなくて大丈夫です。
A/B テストで施策の効果を検証!エンジニアのための R 入門 - クックパッド開発者ブログ
連続性の補正というのは、カイ二乗検定は、この分布が連続した関数であるカイ二乗分布に従うという仮定で行うのですが、実際には人が0.1人とかそんな分離の仕方しないので、その補正の為に行うものです。
で。
これだけ例数が多いと、一人程度での不連続はあんま意識しなくていいので補正は入れなくてもいいでしょう。
そこら辺の丁寧な説明は
Fisherの正確検定かカイ2乗検定か
とかにあります。
ちなみに、他によく使うのは青木先生の所とか。
「経営判断が変わるほど結果に影響を及ぼすことはまずないと思われる」は、サンプルサイズが小さい時には可能性としてありますが、サンプルサイズが小さい時には、二項検定使うでしょうね。
というか、A/Bテストの結果が経営判断に直結するというのは、そもそも会社の経営として頭がおかしだけという話もありますが。
という事を考えた方がいいです。逆に、「どれぐらいの差があった時に検出できるようにするか」という事を検討していった方がいいでしょう。
A/Bテストを「した方がいいのか」というのも、一つの判断になります。
このあたりの人に、たまにあるのですが、CVRの足し算引き算して前後比較するのに躊躇いがない人がたくさんいます。
一見正しそうですが、サンプルサイズおんなじだった?とかそういう情報ガスガス落としたスライド見る事も多いです。
また、1回のテストでは、どうしてもそれに紛れ込んでくる影響が気になります。タイミングの影響がそこはかとなく存在したりする場合もあるわけですよ。そういうすべての要因を考慮するのは難しいのですが、
という二律背反な所があります。
1%ぐらいのCVRなら、幾らテストで高い評価を得てたとしても、おそらくどんなユーザに届いたかとかの方が影響が大きく、そこに金をかけるのは効果的ではない、というような感じですね。
まああと、A/Bテストとかで画面考えてくのって、どちらかと言うとメンテナンスモードの改修で使えるか、ぐらいですねえ本当は。
サイトの成長期なら、テストで出てくる確率ほどの信頼性は当然ないです。検定とかではあくまでテストの対立・帰無仮説を包む大きな仮説が成り立つ時、使えるというものだったりするので。
まあ、SASに限らずだけど。
SASの資格は大したものは持っていないのだけど、体系だってSASを学んだと言うより鬼のような現状に鍛え上げられたという感じなので、ほぼほぼ大概の事は何とかなるようになってる。
んだけど、流石にSAS/GRAPH周りは普段やってない(やる気しない)のでキツい。
EMFという形式でファイルが出力出来るんだが、バージョン違いだとIEだと見えない、という事象が発生した。9.1.3と9.4。
ペイントだと見える。
意味が分からんので、GDEVICEプロシージャで眺め、差分をModifyしたが、結果変わらず。
テクサポに投げたら、9.3でその辺りだいぶ変わってるとの事。うん、まあ、html標準出力とかは大枠は知ってるけど、多分それ関係ないねんと思いながら眺め倒す事にしたら、EMF"Plus"という記述が。
ほう。
Dual形式では見えるとか、EMF形式のパターンでも見えたので、おそらくこれと。
勘弁してくれ。
ファイル拡張子も含め、EMFとして組まれているシステムをどうやって改造すりゃいいのか途方に暮れる。
無論、GDEVICEでエントリ置き換える事もやってみたが、全く効果なし。
どうやらGDEVICEで設定されるレベルでは挙動変えられないっぽい。
悩みに悩んだが、ふと思い立ち、SASのRegistryがあるのを思い出した。たまにfontregでその辺り弄る人はいるだろうけど。
EMF設定のRegistryをEMFPlusの設定で上書きし、無事動く事を確認。
そろそろ、SASの仕組みの裏側覗くような仕事は辞めたい。
正直な所、コレをクリアしたらまた大した事のない風に思われるんだろうなあ。
誰やねん、簡単に移行出来るって客に言ったヤツ。
という辺りで詰まってますなー。
GNOMEでのSETTINGもしましたが。
sudoでもENVKEEP設定もしましたが。
結局の所、dconfだったかが、「接続出来ませんねん」みたいなメッセージを出して来る、あの問題をどう解決するかがちょっと目処つかないので、
「proxyの設定を二重にやってます」。
まあでも、ホストOS側でリバースプロキシとか立てないでやってます。
本当はそれがいいのかもですが、ネットワークの領域には踏み込まない。踏み込まないよ!!!!!
通常の設定だと、CDマウントが、その時デスクトップ開いていたユーザで設定されますね。
また、VBOXの共有フォルダは、vboxsfだったかのグループに所属するユーザだけが権限ありますね。
・・・・・・みたいなのを変えたいんですが、自動マウントはudisks2かで実施されており・・・・・・・みたいな話までしか追いかけられてません。
変態な話ですが、ログインユーザと違うユーザでDVDドライブから共有フォルダを参照しつつインストールを行いたい、という事に向けて、やたら調査中。
いや、分かってんねん、fstabという逃げ手はな。ただ、ワザワザ新しい仕組みがあるのにfstabで設定するというのもちと嫌だし。
コア数とかSSDとかに大して興味はないんですが、ビッグデータ解析にもマイナス評価なんですが、ベイズ解析とかがガンガン出来る環境上で、SAS構築するのはしたいなと思ってはいるんですよね。
今、単純にマシンスペック入れるだけでは性能が大して上がらないというような状況になりつつあります。
普通の解析なら十分だと思うんですけど、マルチコアマルチスレッドとか考えだすと、システムの仕掛けからまだチューニングとかでざっくりですが数十倍出せると思うんですよね。
・・・・・・プログラムの効率化、じゃなくて、今のOSやシステムの発展は、インタラクティブ型と言いますか、リアルタイムに複数のプログラムを同時に動かす事を前提にしてます。で、要はハードの上に幾つもの階層のVMが想定されているようなもんなんで、普通に動かすには問題ないパラメータで設定はされているんですがね。
やはりパラレルに動こうが巨大なバッチとして捉える方がチューニングとしては向いているんじゃないかなと思うわけです。
・・・・・・しかし、こんな話を上の方とか親会社があんまり楽しく受け取ってくれないんですよね。
頼むからそういうことさせてくれ、とは思うんですが。上の会社にくっついている総合研究所とかそんな所が真面目にそういう事考えるかというと・・・・・・今はあんまりしてくれないですしね。
使えないからほぼほぼ自分で全部インターネットで調べてやってたりするんですが、もうそれで「売上が~」とか言われるのも辛いですし、ホントどうにかして欲しいです。
SASですが。
「Analytics Pro」であるとか、そういう名前でご指定下さい。マジで。
SAS V8以降、SASのライセンスの呼び方や体系が変わってるんです。
現在、サーバに入れるSASの場合、通常はSAS Enterprise GuideやSAS Studio経由でアクセスするもの、というライセンス体系になってますので、SAS Integration Technologyインストールが普通になってます。要らないと言ってもライセンスには入ってきます。
で。
ライセンスには入って来るんですが、もちろん、そういうサーバ設定を作らなくても使えはするのです。まあ。
ただ、リモートデスクトップ接続で利用する場合にはWindowsサーバ側の設定がいりますし、Linux/VNCだったらVNCの設定いりますし、X Clientでの接続でも似たようなもんです。面倒臭いと言われたらどれもこれも面倒臭いですが。
サーバ構成しちゃうなら、じゃあデータはどこに置くのとかどうファイル持ち込むのとか決めてく必要があります。ただSASをエンジンとして利用したいだけだとかどんどん使い方を決めて行って下さい。
まあでもせっかくサーバ構成しても、WebDAVの部分とかもろくに使われないんですよね・・・・・・
トランスコーディングは、大抵の場合、データセットの別環境への移送も含みます。
ので、そこら辺も絡めてちょっと言及しておきます。
SASの文字変数は、固定長文字列としてバイト長で定義されています。その為、トランスコーディングに伴う文字列の実際のバイト長に対して問題が起きやすいです。
また、固定長文字列で実際のデータも配置される為、RDBMSなどでは普通に行える事であっても出来ないあるいは難易度の高い事があります。文字列長を簡単には変更出来ません。
以下の例をご覧下さい。
/* テストデータはWORK.CLASS */ data WORK.CLASS ; set SASHELP.CLASS ; run ; /* 列定義変更っぽい事をしてみる */ data WORK.CLASS ; set WORK.CLASS ; length NAME $100 ; run ;
328 /* テストデータはWORK.CLASS */ 329 data WORK.CLASS ; 330 set SASHELP.CLASS ; 331 run ; NOTE: データセットSASHELP.CLASSから19オブザベーションを読み込みました。 NOTE: データセットWORK.CLASSは19オブザベーション、5変数です。 NOTE: DATAステートメント処理(合計処理時間): 処理時間 0.00 秒 CPU時間 0.01 秒 332 333 /* 列定義変更っぽい事をしてみる */ 334 data WORK.CLASS ; 335 set WORK.CLASS ; 336 length NAME $100 ; WARNING: 文字変数Nameの長さはすでに設定されています。 文字変数の長さを宣言するには、 DATAステップの最初にLENGTHステートメントを使用してください。 337 run ; NOTE: データセットWORK.CLASSから19オブザベーションを読み込みました。 NOTE: データセットWORK.CLASSは19オブザベーション、5変数です。 NOTE: DATAステートメント処理(合計処理時間): 処理時間 0.00 秒 CPU時間 0.01 秒
/* テストデータはWORK.CLASS */ data WORK.CLASS ; set SASHELP.CLASS ; run ; /* 列定義変更前の定義を取得 */ proc contents data=WORK.CLASS out=WORK.CLASSDEF1 (keep=LIBNAME MEMNAME VARNUM NAME TYPE LENGTH FORMAT: IN:) noprint ; quit ; /* 列定義変更 */ proc sql ; alter table WORK.CLASS modify NAME length 100 ; quit ; /* 列定義変更後の定義を取得 */ proc contents data=WORK.CLASS out=WORK.CLASSDEF2 (keep=LIBNAME MEMNAME VARNUM NAME TYPE LENGTH FORMAT: IN:) noprint ; quit ; /* 列定義変更の前後の差を比較するも完全一致 */ proc sort data=WORK.CLASSDEF1 ; by LIBNAME MEMNAME VARNUM ; quit ; proc sort data=WORK.CLASSDEF2 ; by LIBNAME MEMNAME VARNUM ; quit ; proc compare base=WORK.CLASSDEF1 comp=WORK.CLASSDEF2 method=absolute note ; id LIBNAME MEMNAME VARNUM ; quit ;
807 /* テストデータはWORK.CLASS */ 808 data WORK.CLASS ; 809 set SASHELP.CLASS ; 810 run ; NOTE: データセットSASHELP.CLASSから19オブザベーションを読み込みました。 NOTE: データセットWORK.CLASSは19オブザベーション、5変数です。 NOTE: DATAステートメント処理(合計処理時間): 処理時間 0.00 秒 CPU時間 0.01 秒 811 812 /* 列定義変更前の定義を取得 */ 813 proc contents 814 data=WORK.CLASS 815 out=WORK.CLASSDEF1 816 (keep=LIBNAME MEMNAME VARNUM NAME TYPE LENGTH FORMAT: IN:) 817 noprint 818 ; 819 quit ; NOTE: データセットWORK.CLASSDEF1は5オブザベーション、12変数です。 NOTE: PROCEDURE CONTENTS処理(合計処理時間): 処理時間 0.00 秒 CPU時間 0.01 秒 820 821 /* 列定義変更 */ 822 proc sql ; 823 alter table WORK.CLASS 824 modify NAME length 100 825 ; NOTE: テーブルWORK.CLASS (5列)は変更されました。 826 quit ; NOTE: PROCEDURE SQL処理(合計処理時間): 処理時間 0.00 秒 CPU時間 0.01 秒 827 828 /* 列定義変更後の定義を取得 */ 829 proc contents 830 data=WORK.CLASS 831 out=WORK.CLASSDEF2 832 (keep=LIBNAME MEMNAME VARNUM NAME TYPE LENGTH FORMAT: IN:) 833 noprint 834 ; 835 quit ; NOTE: データセットWORK.CLASSDEF2は5オブザベーション、12変数です。 NOTE: PROCEDURE CONTENTS処理(合計処理時間): 処理時間 0.01 秒 CPU時間 0.01 秒 836 837 /* 列定義変更の前後の差を比較するも完全一致 */ 838 proc sort data=WORK.CLASSDEF1 ; 839 by LIBNAME MEMNAME VARNUM ; 840 quit ; NOTE: データセットWORK.CLASSDEF1から5オブザベーションを読み込みました。 NOTE: データセットWORK.CLASSDEF1は5オブザベーション、12変数です。 NOTE: PROCEDURE SORT処理(合計処理時間): 処理時間 0.00 秒 CPU時間 0.01 秒 841 proc sort data=WORK.CLASSDEF2 ; 842 by LIBNAME MEMNAME VARNUM ; 843 quit ; NOTE: データセットWORK.CLASSDEF2から5オブザベーションを読み込みました。 NOTE: データセットWORK.CLASSDEF2は5オブザベーション、12変数です。 NOTE: PROCEDURE SORT処理(合計処理時間): 処理時間 0.00 秒 CPU時間 0.01 秒 844 proc compare 845 base=WORK.CLASSDEF1 846 comp=WORK.CLASSDEF2 847 method=absolute 848 note 849 ; 850 id LIBNAME MEMNAME VARNUM ; 851 quit ; NOTE: 不等な値はありません。比較した変数はすべて同等でした。 NOTE: データセットWORK.CLASSDEF1とWORK.CLASSDEF2は完全に同等です。 NOTE: データセットWORK.CLASSDEF1から5オブザベーションを読み込みました。 NOTE: データセットWORK.CLASSDEF2から5オブザベーションを読み込みました。 NOTE: PROCEDURE COMPARE処理(合計処理時間): 処理時間 0.02 秒 CPU時間 0.01 秒
最初の方法では、エラーになりますし、二番目の方法では、エラーを吐かないですが変更されていません。
ちょっと回りくどいですが、以下のような方法で変更は可能ではあります。(サンプルはあんまり美しくはないのですが、でも面倒臭いのでそのまま)
/* テストデータはWORK.CLASS */ data WORK.CLASS ; set SASHELP.CLASS ; run ; /* 列定義変更前の定義を取得 */ proc contents data=WORK.CLASS out=WORK.CLASSDEF1 (keep=LIBNAME MEMNAME VARNUM NAME TYPE LENGTH FORMAT: IN:) noprint ; quit ; /* 列定義変更 */ data WORK.CLASS ; length Name $100 ; set WORK.CLASS ; run ; /* このままだと変数の並び順がおかしい。 変数を元の並び順にする場合には 以下のような事をする(他にもやりようはある) */ %let _WK_VARLIST = ; proc sql ; select cats(NAME) into:_WK_VARLIST separated by ',' from WORK.CLASSDEF1 order by LIBNAME,MEMNAME,VARNUM ; quit ; proc sql ; create table WORK.CLASS as select &_WK_VARLIST. from WORK.CLASS ; quit ; %symdel _WK_VARLIST ; /* 列定義変更後の定義を取得 */ proc contents data=WORK.CLASS out=WORK.CLASSDEF2 (keep=LIBNAME MEMNAME VARNUM NAME TYPE LENGTH FORMAT: IN:) noprint ; quit ; /* 列定義変更の前後の差を比較する (Variable:Nameについては若干イカサマしているのでこの例では 変更点としては出ないが Capが定義情報の差として出る事はしばしばある) */ proc sort data=WORK.CLASSDEF1 ; by LIBNAME MEMNAME VARNUM ; quit ; proc sort data=WORK.CLASSDEF2 ; by LIBNAME MEMNAME VARNUM ; quit ; proc compare base=WORK.CLASSDEF1 comp=WORK.CLASSDEF2 method=absolute note ; id LIBNAME MEMNAME VARNUM ; quit ;
1043 /* テストデータはWORK.CLASS */ 1044 data WORK.CLASS ; 1045 set SASHELP.CLASS ; 1046 run ; NOTE: データセットSASHELP.CLASSから19オブザベーションを読み込みました。 NOTE: データセットWORK.CLASSは19オブザベーション、5変数です。 NOTE: DATAステートメント処理(合計処理時間): 処理時間 0.00 秒 CPU時間 0.00 秒 1047 1048 /* 列定義変更前の定義を取得 */ 1049 proc contents 1050 data=WORK.CLASS 1051 out=WORK.CLASSDEF1 1052 (keep=LIBNAME MEMNAME VARNUM NAME TYPE LENGTH FORMAT: IN:) 1053 noprint 1054 ; 1055 quit ; NOTE: データセットWORK.CLASSDEF1は5オブザベーション、12変数です。 NOTE: PROCEDURE CONTENTS処理(合計処理時間): 処理時間 0.01 秒 CPU時間 0.00 秒 1056 1057 /* 列定義変更 */ 1058 data WORK.CLASS ; 1059 length Name $100 ; 1060 set WORK.CLASS ; 1061 run ; NOTE: データセットWORK.CLASSから19オブザベーションを読み込みました。 NOTE: データセットWORK.CLASSは19オブザベーション、5変数です。 NOTE: DATAステートメント処理(合計処理時間): 処理時間 0.00 秒 CPU時間 0.00 秒 1062 /* 1063 このままだと変数の並び順がおかしい。 1064 変数を元の並び順にする場合には 1065 以下のような事をする(他にもやりようはある) 1066 */ 1067 %let _WK_VARLIST = ; 1068 proc sql ; 1069 select cats(NAME) into:_WK_VARLIST separated by ',' 1070 from WORK.CLASSDEF1 order by LIBNAME,MEMNAME,VARNUM ; NOTE: 指定したクエリにはSELECT句にない項目によるソートが含まれます。 1071 quit ; NOTE: PROCEDURE SQL処理(合計処理時間): 処理時間 0.01 秒 CPU時間 0.01 秒 1072 1073 proc sql ; 1074 create table WORK.CLASS 1075 as select &_WK_VARLIST. from WORK.CLASS 1076 ; WARNING: This CREATE TABLE statement recursively references the target table. A consequence of this is a possible data integrity problem. NOTE: テーブルWORK.CLASS(行数19、列数5)が作成されました。 1077 quit ; NOTE: PROCEDURE SQL処理(合計処理時間): 処理時間 0.01 秒 CPU時間 0.01 秒 1078 %symdel _WK_VARLIST ; 1079 1080 /* 列定義変更後の定義を取得 */ 1081 proc contents 1082 data=WORK.CLASS 1083 out=WORK.CLASSDEF2 1084 (keep=LIBNAME MEMNAME VARNUM NAME TYPE LENGTH FORMAT: IN:) 1085 noprint 1086 ; 1087 quit ; NOTE: データセットWORK.CLASSDEF2は5オブザベーション、12変数です。 NOTE: PROCEDURE CONTENTS処理(合計処理時間): 処理時間 0.01 秒 CPU時間 0.01 秒 1088 1089 /* 列定義変更の前後の差を比較する 1090 (Variable:Nameについては若干イカサマしているのでこの例では 1091 変更点としては出ないが 1092 Capが定義情報の差として出る事はしばしばある) */ 1093 proc sort data=WORK.CLASSDEF1 ; 1094 by LIBNAME MEMNAME VARNUM ; 1095 quit ; NOTE: データセットWORK.CLASSDEF1から5オブザベーションを読み込みました。 NOTE: データセットWORK.CLASSDEF1は5オブザベーション、12変数です。 NOTE: PROCEDURE SORT処理(合計処理時間): 処理時間 0.00 秒 CPU時間 0.01 秒 1096 proc sort data=WORK.CLASSDEF2 ; 1097 by LIBNAME MEMNAME VARNUM ; 1098 quit ; NOTE: データセットWORK.CLASSDEF2から5オブザベーションを読み込みました。 NOTE: データセットWORK.CLASSDEF2は5オブザベーション、12変数です。 NOTE: PROCEDURE SORT処理(合計処理時間): 処理時間 0.00 秒 CPU時間 0.01 秒 1099 proc compare 1100 base=WORK.CLASSDEF1 1101 comp=WORK.CLASSDEF2 1102 method=absolute 1103 note 1104 ; 1105 id LIBNAME MEMNAME VARNUM ; 1106 quit ; NOTE: 次の1変数の値は不等です: LENGTH NOTE: データセットWORK.CLASSDEF1とWORK.CLASSDEF2には不等な値があります。 NOTE: データセットWORK.CLASSDEF1から5オブザベーションを読み込みました。 NOTE: データセットWORK.CLASSDEF2から5オブザベーションを読み込みました。 NOTE: PROCEDURE COMPARE処理(合計処理時間): 処理時間 0.01 秒 CPU時間 0.01 秒
巷では、ほぼUTF-8でエンコーディングを寄せるという発想が主流です。
日本語の取り扱いで、SASでは今でもデフォルトはSJISですし、SJISの方が良いことも多々あります。
逆に、SASの世界で何故今でもSJISが使われているかというと、
です。
ただ、国際化の今、SJISでは中国語や韓国語を取り扱えませんし、各種ツールもUTF-8対応が十分に進んでいる為、そろそろユーザ側に近いアプリケーションではあるSASもUTF-8を基本として使う方がいいと思います。
まあ、経験上、例えばJavaやWebアプリはUnicodeが基本ですし、各システムとの連携でももうUnicodeでない方が問題が多い所もありますし。
SJISからUTF-8へ変換する、SJISのデータセットをそのまま使う、際に、現状のSASでは、必ず手当が必要です。
SAS 9.4各国語サポート(NLS): リファレンスガイド(PDF)については、一度読むことをオススメします。
SJISのデータセットであっても、V8以降では、本来は特に文字コード変換を描けなくても、使用時に自動的に変換してくれる、CEDA(Cross-Environment Data Access)という機能が使えるはずです。
はずなんですが、SJISからUTF8環境へのCDEAの適用の場合、ほぼCVPオプションによる「対応」が必須です。
CEDAの機能が中途半端だなあと。
CVPオプションは、主に倍率の方を使用されると思いますが、例えば、SJISとUTF8では、「だいたいは1.5倍で大丈夫」です。
ただ、ちょっとヤバイ所がありまして、第三水準、第四水準の実装がShift_JIS-2004ベースで為されている場合の文字は4バイトになるので問題が発生します。
が、元々ちょっと取り扱いしていないだろうとは思います。WindowsだとSJIS実装されてなかったはずですし
/* SJIS環境で実施 */ libname TEST "C:\temp" ; proc copy in=SASHELP out=TEST ; select CLASS ; quit ;
/* UTF8環境で実施 */ libname TEST "C:\temp" ; data _null_ ; set TEST.CLASS ; putlog _all_ ; run ;
14 /* UTF8環境で実施 */ 15 libname TEST "D:\temp" ; NOTE: ライブラリ参照名TESTを次のように割り当てました。 エンジン: V9 物理名: D:\temp 16 data _null_ ; 17 set TEST.CLASS ; NOTE: データファイルTEST.CLASS.DATAは別なホストにネイティブな形式が使用されているか 、またはエンコーディングがセッションエンコーディングと一致していません。 クロス環境データアクセスが使用されるため、追加のCPUリソースが必要となり、 パフォーマンスが低下します。 18 putlog _all_ ; 19 run ; WARNING: データセットTEST.CLASSのトランスコード時に文字データが一部損失しました。 新しいエンコーディングで表せない文字がデータに含まれていたか、またはト ランスコード時に切り捨てが発生しました。 Name=アルフレ Sex=男 Age=14 Height=69 Weight=112.5 _ERROR_=0 _N_=1 Name=アリス Sex=女 Age=13 Height=56.5 Weight=84 _ERROR_=0 _N_=2 Name=バーバラ Sex=女 Age=13 Height=65.3 Weight=98 _ERROR_=0 _N_=3 Name=キャロル Sex=女 Age=14 Height=62.8 Weight=102.5 _ERROR_=0 _N_=4 Name=ヘンリー Sex=男 Age=14 Height=63.5 Weight=102.5 _ERROR_=0 _N_=5 Name=ジェーム Sex=男 Age=12 Height=57.3 Weight=83 _ERROR_=0 _N_=6 Name=ジェーン Sex=女 Age=12 Height=59.8 Weight=84.5 _ERROR_=0 _N_=7 Name=ジャネッ Sex=女 Age=15 Height=62.5 Weight=112.5 _ERROR_=0 _N_=8 Name=ジェフリ Sex=男 Age=13 Height=62.5 Weight=84 _ERROR_=0 _N_=9 Name=ジョン Sex=男 Age=12 Height=59 Weight=99.5 _ERROR_=0 _N_=10 Name=ジョイス Sex=女 Age=11 Height=51.3 Weight=50.5 _ERROR_=0 _N_=11 Name=ジュディ Sex=女 Age=14 Height=64.3 Weight=90 _ERROR_=0 _N_=12 Name=ルイーズ Sex=女 Age=12 Height=56.3 Weight=77 _ERROR_=0 _N_=13 Name=メアリー Sex=女 Age=15 Height=66.5 Weight=112 _ERROR_=0 _N_=14 Name=フィリッ Sex=男 Age=16 Height=72 Weight=150 _ERROR_=0 _N_=15 Name=ロバート Sex=男 Age=12 Height=64.8 Weight=128 _ERROR_=0 _N_=16 Name=ロナルド Sex=男 Age=15 Height=67 Weight=133 _ERROR_=0 _N_=17 Name=トーマス Sex=男 Age=11 Height=57.5 Weight=85 _ERROR_=0 _N_=18 Name=ウィリア Sex=男 Age=15 Height=66.5 Weight=112 _ERROR_=0 _N_=19 NOTE: データセットTEST.CLASSから19オブザベーションを読み込みました。 NOTE: DATAステートメント処理(合計処理時間): 処理時間 0.03 秒 CPU時間 0.03 秒
/* UTF8環境で実施 */ libname TEST "D:\temp" cvpmultiplier=1.5 ; data _null_ ; set TEST.CLASS ; putlog _all_ ; run ;
26 /* UTF8環境で実施 */ 27 libname TEST "D:\temp" cvpmultiplier=1.5; NOTE: ライブラリ参照名TESTを次のように割り当てました。 エンジン: CVP 物理名: D:\temp 28 data _null_ ; 29 set TEST.CLASS ; NOTE: データファイルTEST.CLASS.DATAは別なホストにネイティブ な形式が使用されているか、またはエンコーディング がセッションエンコーディングと一致していません。 クロス環境データアクセスが使用されるため、追加の CPUリソースが必要となり、パフォーマンスが低下しま す。 30 putlog _all_ ; 31 run ; Name=アルフレッド Sex=男子 Age=14 Height=69 Weight=112.5 _ERROR_=0 _N_=1 Name=アリス Sex=女子 Age=13 Height=56.5 Weight=84 _ERROR_=0 _N_=2 Name=バーバラ Sex=女子 Age=13 Height=65.3 Weight=98 _ERROR_=0 _N_=3 Name=キャロル Sex=女子 Age=14 Height=62.8 Weight=102.5 _ERROR_=0 _N_=4 Name=ヘンリー Sex=男子 Age=14 Height=63.5 Weight=102.5 _ERROR_=0 _N_=5 Name=ジェームズ Sex=男子 Age=12 Height=57.3 Weight=83 _ERROR_=0 _N_=6 Name=ジェーン Sex=女子 Age=12 Height=59.8 Weight=84.5 _ERROR_=0 _N_=7 Name=ジャネット Sex=女子 Age=15 Height=62.5 Weight=112.5 _ERROR_=0 _N_=8 Name=ジェフリー Sex=男子 Age=13 Height=62.5 Weight=84 _ERROR_=0 _N_=9 Name=ジョン Sex=男子 Age=12 Height=59 Weight=99.5 _ERROR_=0 _N_=10 Name=ジョイス Sex=女子 Age=11 Height=51.3 Weight=50.5 _ERROR_=0 _N_=11 Name=ジュディー Sex=女子 Age=14 Height=64.3 Weight=90 _ERROR_=0 _N_=12 Name=ルイーズ Sex=女子 Age=12 Height=56.3 Weight=77 _ERROR_=0 _N_=13 Name=メアリー Sex=女子 Age=15 Height=66.5 Weight=112 _ERROR_=0 _N_=14 Name=フィリップ Sex=男子 Age=16 Height=72 Weight=150 _ERROR_=0 _N_=15 Name=ロバート Sex=男子 Age=12 Height=64.8 Weight=128 _ERROR_=0 _N_=16 Name=ロナルド Sex=男子 Age=15 Height=67 Weight=133 _ERROR_=0 _N_=17 Name=トーマス Sex=男子 Age=11 Height=57.5 Weight=85 _ERROR_=0 _N_=18 Name=ウィリアム Sex=男子 Age=15 Height=66.5 Weight=112 _ERROR_=0 _N_=19 NOTE: データセットTEST.CLASSから19オブザベーションを読み込 みました。 NOTE: DATAステートメント処理(合計処理時間): 処理時間 0.11 秒 CPU時間 0.07 秒
注意点としては、「元データセットを更新する訳ではないですが」、「定義から1.5倍された状態で見えます」。
例えば、SJISで長さ12バイトとして定義されていたデータセットは、cvpmultiplier=1.5で、18バイト元からあったように見えます。
CVPオプションは、文字列変数の「変数長に対してのみ効果が出ます」。
さて。
最近、しばしば見かけるデータセットでは、何故かわざわざ文字変数に同じ長さの文字フォーマットを設定している事があります。
Enterprise GuideでExcelファイルを取り込んだりするとそういうのが出来てたりします。
そういったフォーマットが付けられている場合に、自動でフォーマット長も設定されてたりするんですね。その場合には、「フォーマットの長さは変更されません」。
そういう場合には、フォーマットの設定を外して下さい。「format _all_ ;」で消えます。が、まあ、WORKなど現在の環境に複写してUTF8に変換された状態でないとダメです(元データは違うエンコーディングで、更新は出来ません)。
SDTMとか扱っている場合には、そもそも変数にフォーマット付けない方がいいです。XPORTファイル、フォーマットカタログに対応していないですし。
何だか騒がしくなってきた所ですが(超白々しい)、最近話題のSAS transport fileというのを簡単にご説明させて頂きます。
XPORTファイルを送る場合には、送り先と受け先の文字エンコーディングが一致していることが前提なんです。
大事な事なので二回言いますが、XPORTファイルには文字エンコーディングの情報は入ってません。
XPORTファイルは、しかし、それ以外のケース、例えばOSの違いは吸収します。bit数の違いは、数値変数に設定した長さでのIBM形式であると定義されているので差になりません。
で。
そもそもで言うと、SAS XPORT形式は、ASCII以外の文字列を特にサポートはしてないのです。
それどころか、もっと低レベルな範囲でのサポートにとどまります。
蛇足ですが、移送形式なので、プラットフォームが違っても同一の形式になります。
プラットフォームに依存する問題はこの形式では発生しません。
実はV8のXPORT形式というのも出てきており、V5形式の拡張ながらちょっとはマシになってます。
けど、FDAが言っているのは、SAS V5 transport file formatですので、それの制約がとっても重くのしかかってます。のしかかりすぎです。二十年前に辞めたかったような制約がそのまんま課せられてます。
データセット名・変数名の最大長は8バイトとか、ラベルも40バイトとか、フォーマット定義名も8文字以下とか(文字フォーマットの場合には$も入るので7文字まで)、かなりの制約があります。ちなみにカタログファイルは転送出来ないので、ユーザ定義フォーマットとか禁止。
つまりは、SAS V6ぐらいでも使えるようなデータの形式であるという事です。
ちなみに、文字エンコーディングはサポートされてはないのですが、同じ文字エンコーディングである場合には同じ文字エンコーディングで出力されるし読めるという感じです。
VirtualBoxが気にはなってたけど、今までWin7でインストール出来ずに四苦八苦していたけど、とりあえずインストールする方法が見つかったので乗り換えてみる。
Windows 7 Professionalではなんでかx32版をインストーラーがインストールしようとしてコケてるようで。
その為、インストーラーからmsiを抽出してから実行してみた。
引数は-extractで。
%temp%\VirtualBoxに展開されるので、そこからAMDx64を選択してインストール。
左側の方が幸せかもしんない。