SAS xportファイルに仕様上の不備?
ちょっと前にSASxportファイルへのアクセスを試してみましたが、その際、おかしな挙動をしたのでまとめておきます。
(2020/11/20追記)
とりあえず以下のプログラムを実行してみます
options dlcreatedir; libname temp 'c:\temp'; data test1 test2; array a{3} $2; do i=1 to 3; a{i}=' A'; end; output test1 test2; output test1; do i=1 to 3; a{i}=' '; end; output test2; drop i; run;
workライブラリに作成されるデータセットは以下の2obs、3変数のものです。
続いて、この2つのデータセットをtext.xptというxport形式のファイルに変換し、再度tempライブラリにsasデータセットとして再変換しています。
libname out xport 'c:\temp\test.xpt'; proc copy in=work out=out; select test:; run; proc copy in=out out=temp; select test:; run;
この結果生成されるデータセットは以下の通りです。
test2の2obs目が失われています。
SASxportの仕様を調べたところ、バイナリファイルは1ブロック80バイトで構成されており、ヘッダー部分、データ部分それぞれにおいて、最後が80バイトに満たない場合は80バイトまで空白で埋める(padding)、という挙動をするようですが、文字列についてはそのままバイナリに保存されているため、空obs(欠損)と空白のpaddingが区別できていないのでは?と思います。
その結果、
・データセットに含まれる変数がすべて文字変数
かつ
・最後のobsがすべて欠損
かつ
・行のバッファ(すべての変数長の合計)が 80 40以下(その後の検証で41以上なら削除されないことが分かりましたので訂正しました)
の場合に最後の欠損obsが復元できなくなる、という結果になります。
(数値変数の場合、8バイトにフラグ1バイトと数値領域7バイトが確保され、obsのデータという識別ができるため、数値変数が1つでも存在すれば問題ありません)
どうにかならんもんですかねぇ。
せめてobs数を保持していれば、と思うのですが。
(2020/11/20追記)
どうも米国本社では不具合として認識しているようで、将来的なバージョンでの対応を予定しているとのこと。
早く不具合諸々修正したSAS 10(SAS Xとか)でも出てほしいのですが、Viyaがリリースされてしまっているので、PC版SASの更新は当面なさそう。
単純にヘッダーにobs数を埋め込むだけでいいと思うんですけど、旧バージョンのSASや3rdパーティー関係で影響がありそうなのでなんとも。
まぁ、SASxportを使用するCDISCで言えば、全てが欠損のobsなんて発生し得ないわけで、実際には影響は極々軽微と思われます。
私のような仕様バkに突っ込まれる程度で。