「INFILEで外部ファイルを読み込むときに指定する ”DSD MISSOVER” ってどういう役割?」
って質問をよくもらいます。
具体例で各オプションの役割を見ていきましょう。
外部ファイルからカンマ(,)等の区切り記号毎に値を区切って読み込む際、挙動を細かく設定するオプションです。
例1
読み込むCSVファイル … C:\test\sample1.csv
1,,2
|
*** DSDあり ; data OUT1; length A B C 8.;
infile "C:\test\sample1.csv" dlm="," dsd missover ; input A B C; run;
*** DSDなし ;
data OUT1;
length A B C 8.; infile "C:\test\sample1.csv" dlm="," missover ; input A B C; run;
|
- 上記テキストファイルで「1,,2」 というように区切り記号が連続する部分をDSDオプションにより欠損値として扱うよう設定できます。
- またこの例では分からないですが、DSDを指定することによって、区切り記号のデフォルトがカンマ(,)に変わります(デフォルトは半角スペース)。区切り記号は「DLM=オプション」で変更可能です。
読み込むCSVファイル … C:\test\sample2.csv
1,2,"x, y and z" |
*** DSDあり ; data OUT2; length A B 8. C $10.; infile "C:\test\sample2.csv" dlm="," dsd missover ; input A B C; run;
*** DSDなし ; data OUT2; length A B 8. C $10.; infile "C:\test\sample2.csv" dlm="," missover ;input A B C; run;
|
DSDの挙動として、
テキストファイルが「"x, y and z"」というようにクォーテーションで囲まれていると、そのクォーテーションを取り除いた上で中の文字全体を区切り記号もろとも1つの変数に読み込むことが出来ます。
MISSOVERの役割
読み込むCSVファイル : C:\test\sample3.csv
「input A B C;」 というように変数を3つ割り当てていますが、
テキストファイルの1行目は 「1,2」 となっているので変数Cを割り当てるデータがありません。
(変数Cを欠損値にしたいのであれば 「1,2,」 というように区切り記号を最後にもつける)
なので、SASは足りない部分を次の行から取ってこようとしちゃいます。
MISSOVERは足りない部分を「欠損値で埋める」という処理をしてくれます。
ただし!
読み込むCSVファイル : C:\test\sample3.csv
1,2
3,4,5 |
*** MISSOVERあり ;
data OUT3; length A B C 8.; infile "C:\test\sample3.csv" dlm="," dsd missover ; input A B C; run;
*** MISSOVERなし ;
data OUT3;
length A B C 8.; infile "C:\test\sample3.csv" dlm="," dsd; input A B C; run;
|
「input A B C;」 というように変数を3つ割り当てていますが、
テキストファイルの1行目は 「1,2」 となっているので変数Cを割り当てるデータがありません。
なので、SASは足りない部分を次の行から取ってこようとしちゃいます。
MISSOVERは足りない部分を「欠損値で埋める」という処理をしてくれます。
MISSOVERより「TRUNCOVER」というオプションを使用すべき場合があるのでご注意ください
(以下、海外のPaper参照。挙動が分かりやすいです)
読み込むテキストファイル : C:\test\sample4.txt
ちなみに、以下のように後ろを半角スペースで埋めていれば、バイト数が足りないとは判定されません。
一応、軽く説明。
読み込むテキストファイル : C:\test\sample4.txt
a xxx b yy c z |
*** オプション指定なし ; data OUT4; length A B $10.; infile "C:\test\sample4.txt"; input A 1-2 B 3-5; run;
*** MISSOVER ; data OUT4; length A B $10.; infile "C:\test\sample4.txt" missover ; input A 1-2 B 3-5; run;
*** TRUNCOVER ; data OUT4; length A B $10.; infile "C:\test\sample4.txt" truncover ; input A 1-2 B 3-5; run;
|
今回は「input A 1-2 B 3-5;」みたいに、カラム(バイト)指定して読み込んでいますが、「TRUNCOVER」以外は臨んだ結果になっていません。
原因として、INPUTステートメントで「B 3-5」として3~5バイト目を読み込んで変数Bに格納するよう指定していますが、以下の通りテキストファイルの2行目と3行目は5バイト目がありません。
a xxx b yy c z |
- 読み込むバイト数が足りない場合、そのデータの読み込みがスキップされて、上で示した「オプション指定なし」の結果のようにデータがズレた感じで読み込まれちゃいます。
- 「MISSOVER」を指定すると、データのズレはなくなりますが、バイト数が足りない部分は欠損値になっています。
- 「TRUNCOVER」を指定すると、データのズレもなく、バイト数が足りない部分も読み込んでくれています。
a xxx b yy c z |
このように、INFILE・INPUTの指定方法(と、もしかしたら環境)によって挙動が様々なので、都度挙動の確認はした方がよいです。
ちなみに今回のようなデータをCARDSステートメントで読み込む場合はまた挙動が変わります。
なんてややこしい仕様だ!
0 件のコメント:
コメントを投稿