長いタイトルですが、SQLのいいとこ取りした便利技の紹介です。
Sample Data
data DT1; length A $2. B $1.; input A$ B$ ; cards; 01 a 02 b 02 b ; run; data DT2; length A $1. B $2.; input A$ B$; cards; 3 cc 4 dd ; run;
DT2
|
サンプルデータをまずSETで結合してみます。
data OUT1; set DT1 DT2; run; ログ WARNING: 入力データセットによって、変数Bに複数の長さが指定されました。データの切り捨てが発生します。
|
結果を見ると、変数Bの値が、一部文字切れしちゃってますね。
これは、
「set DT1 DT2」 で最初に指定したデータセットDT1にある変数のlengthが、結合後のデータセットに割り当てられるからです。
つまり、変数Bのlengthが、DT1は「$1」、DT2は「$2」と異なっていますが、
上記青字の性質によって、結合時に「$1」が割り当てられます。
なので、DT2から持ってきた変数Bは、length「$1」に合わせて文字を切ってしまいます。
解決法
正攻法として、SETする時にlengthを設定しなおせばokですが、、、
data OUT2; length A B $3.; set DT1 DT2; run; |
「SQLプロシジャ入門14:データセットを縦結合する【UNION】」で紹介した「OUTER UNION CORR」を使えば、
なんと結合するデータセットの中で最大のlengthを勝手に設定してくれます。
proc sql; create table OUT3 as select * from DT1 outer union corr select * from DT2; quit;
|
ただし、SETステートメントと異なる動きあり。
まず、以下のプログラムと結果を見てみましょう。
*** Sample Data ; data DT1; A = .; run; data DT2; format A yymmdd10. ; A = '01jan2015'd ; run; DT1
DT2
*** SETステートメントによる結合 ; data OUT1; set DT1 DT2; run;
*** 「OUTER UNION CORR」による結合 ; proc sql; create table OUT2 as select * from DT1 outer union corr select * from DT2; quit;
|
これは「SETステートメント」の方は、format 「yymmdd10」 が割り当てられていて、
「OUTER UNION CORR」の方は、formatが割り当てられてないというだけで、
値自体は同じものです。
リファレンスから探せなくて確かではないですが、結合したデータセットの format, informat は、
値自体は同じものです。
リファレンスから探せなくて確かではないですが、結合したデータセットの format, informat は、
- 「SETステートメント」: 最初のデータセットDT1にformat, informatが割り当てられてなければ、次のデータセットDT2のformat, informatを割り当てている模様。
- 「OUTER UNION CORR」: 最初のデータセットDT1のものを割り当てている模様。
利用する際はいろいろテストしたり、期待通りの結果になるかご確認ください。
この違いを気にしないシチュエーションであれば、超便利なテクニックですね。
この違いを気にしないシチュエーションであれば、超便利なテクニックですね。
0 件のコメント:
コメントを投稿