2021年12月5日日曜日

「ODS OUTPUT」で変数属性が自動調整される件



「PROC SQL」と「ODS OUTPUT の PERSIST=RUN」のコンボ技 の記事内で


ODS OUTPUTで出力すると変数属性(変数名、length、formatなど)が自動調整される場合がある

と言ったんですが、じゃあ実際どう自動調整されるのか。


結論からいって、

  • 変数属性は自動調整されるけど、データの中身は無事のよう(リファレンスに詳しい挙動が書いてないので、環境やバージョンによって挙動が同じかは不明。。各自で挙動確認してみてください)
  • 私はこのコンボ技を単純な頻度集計で使う程度で支障ないですが、変数属性が自動調整されてしまうのがまずい状況下では、ご注意下さい。




「ODS OUTPUT 」で変数属性がどう自動調整されるのか見てみる。

実行日: 2021/12/03, 実行環境: SAS Ondemand for Academics [SAS 9,4M6])


テストデータ
/*  d1 */
data d1;
  length a b $10. c e 8.;
  label c = "test1";
  format c yymmdd10.;
  a="aaa"; b="bbb"; c=1; e=1;
run;

/*  d2 */
data d2;
  length a $20. b c d e 8.;
  label c = "test2" d="test3";
  format c d time5.;
  a="aaa"; b=1; c=1; d=1; e=1;
run;



「PROC SQL の SELECTステートメント」の結果を「ODS OUTPUT」を使ってデータセットに出力してみます。


例①「データセットd1」を使ってODS OUTPUTで出力
ods select none;
ods output SQL_Results=out1;
proc sql;
  select * from d1;
quit;
ods output close;
ods select all;

各データセットの変数属性
データセットd1
データセットout1 (ODS OUTPUTで出力したやつ)


例②「データセットd2」を使ってODS OUTPUTで出力
ods select none;
ods output SQL_Results=out2;
proc sql;
  select * from d2;
quit;
ods output close;
ods select all;

各データセットの変数属性
データセットd2

データセットout2 (ODS OUTPUTで出力したやつ)


例③「データセットd1とd2」を使って「ODS OUTPUT の PERSIST=」でプロシジャ内の結果を結合して出力
ods select none;
ods output SQL_Results(persist=run)=out3;
proc sql;
  select * from d1;
  select * from d2;
quit;
ods output close;
ods select all;

各データセットの変数属性
データセットout1 (例①で、d1を使ってODS OUTPUTで出力したやつ)
データセットout2 (例②で、d2を使ってODS OUTPUTで出力したやつ)
データセットout3 (例③で、「ODS OUTPUT の PERSIST=」で出力したやつ)



結果の考察


  • formatを割り当てていない数値変数はなぜかbestフォーマットが割り当てられてた(これはどちらかというとSQLプロシジャ側のODS出力時の設定によるものと思われる。このようにODS出力時に勝手にformatが割り当てられる場合がある。割り当てられるformatはプロシジャによって様々)
    • 例①の変数Eなどを参照
  • 「ODS OUTPUT の PERSIST=」で出力結果を結合すると、
    • 同じ変数名(かつ文字変数)でlengthが違う場合 = 大きい方に合わせられた
      • 例③の変数Aなどを参照
    • 同じ変数名で型が違う場合 = 片方の変数がrenameされた。
      • 例③の変数Bなどを参照(結合後、変数Bと変数B2に分かれてる)
    • 同じ変数名でラベルが違う場合 = 最初のデータセットのラベルになった
      • 例③の変数Cなどを参照
    • 同じ変数名でフォーマットが違う場合 = formatが削除された
      • 例③の変数Cなどを参照
    • 片方のデータセットにしか変数がない場合 = 変数がkeepされた。あとformatを割り当てた変数はちゃんとformatが残った。
      • 例③の変数Dなどを参照

他にも私が把握しきれていないだけで「変数属性が自動調整」されるパターンはあると思います。


同じ変数名(かつ文字変数)のlengthが大きい方に合わせられたのと、同じ変数名で型が違う場合に勝手にrenameして両方保持してくれるのは、便利っていえば便利ですね。