- 可変長テキストファイルの読み込みに限定した説明になります。
他の形式で今回のプログラムを流用すると、重要なオプションが効かず、文字切れや変数属性の設定がうまくいかない等の可能性あり。
- とにかく、想定外の結果になりやすいので、出来たデータセットは要確認です。
例えば、聞いた話ですが、テキストファイルに「クォーテーション」「改行コード」「見えない改行コード」が含まれている際に、正しく読み込めない事があったようです。
PROC IMPORT OUT = 出力データセット DATAFILE = "読込テキストファイル" /* パスが長いと実行失敗します */ DBMS = CSV | TAB | DLM /* ファイル種類 */ REPLACE /* 既存のデータセットを置き換える */ ; DELIMITER = "区切り文字"; /* DBMS=DLMの場合に指定 */ GETNAMES = YES | NO ; /* 1行目を変数名として読み込むか */ DATAROW = 行番号 ; /* 何行目から読み込むか */ GUESSINGROWS = 行番号 | MAX; /* 何行目までのデータで変数属性を判定するか */ RUN ; DBMS=オプション
|
📚 注意点
① GUESSINGROWS=オプション ※重要!
SASはテキストファイルの先頭20行を読み込んで各変数の属性(データ型やlength)を決める。
② 制限(環境・バージョンによって異なる可能性あり)
- 20行目まで数値で、21行目に文字が入ってきた場合
- 20行目まで文字の最大長さが100バイトで、21行目に200バイトの文字が入ってきた場合
てことで、変数属性を判定する行数をGUESSINGROWSで設定しなおします。
ちなみに、SAS9.3 から 「GUESSINGROWS = MAX」 という指定が可能(MAX = SASが読込める最大行数)② 制限(環境・バージョンによって異なる可能性あり)
項目 | 内容 |
SASが読込める最大行数 | 32767行【SAS9.2】、2147483647行【SAS9.3, 9.4】 |
1行につき読込めるバイト数 | 区切り文字も含め32767バイト |
③ REPLACEオプション
世代管理されたデータセット(GENMAX=オプション)をREPLACEすると、そのデータセットの既存の世代データがすべて削除されるようなので注意。
④ GETNAMES=オプション
「YES」で1行目を変数名として読み込んだ場合、変数名として成立しない空白・特殊文字などが含まれていると、SASが変数名として成立する名前に変換してくれます。ただ、システムオプション「VALIDVARNAME」の設定によって、変換される変数名が変わるので注意。
最後に、気づいた範囲で「うまく読み込めない例」を紹介。
最後に、気づいた範囲で「うまく読み込めない例」を紹介。
X,Y,Z 001, pen,2016/01/01 002,apple,2016/01/02 |
① 変数X: 0落ち問題
数値変数として読み込まれて、しかも結果が読み込み元の値と異なっている(先頭の0が取れた: 001 → 1 )
読み込み元の値をダブルクォーテーションで囲ったら0落ちしませんでしたが( "001" → 001 )、データステップによるINFILE/INPUTでの読み込みに切り替えた方が良いかもしれませんね。
② 変数Y: 先頭の半角スペース落ち問題
読み込み元の値は「 pen」と先頭に半角スペースを含んでいますが、結果は先頭の半角スペースが取れた。
PROC IMPORTに限らず、SASの色々な機能で先頭の半角スペース取れがち。
③ 変数Y: FORMATとINFORMATが付与される問題
変数属性を見ると、FORMAT(出力形式)とINFORMAT(入力形式)が付与されています。
これは以下のような場合に、勘違いを起こしやすいです。
SET前のLENGTHステートメントでYの長さを増やしてから、Y = "aaaaaaab" としたのに、結果は「aaaaaaa」となった(末尾の "b" が落ちた?)
実はちゃんと "aaaaaaab" が格納されていますが、FORMAT「$7」が付与されているため、見た目7バイト分しか見えていないだけ(この勘違い、よく聞きます)
FORMAT/INFORMATは以下で外せます(外す処理はSET後に記述しないと動作しないので注意)
全変数いっぺんにFORMATを外したいところですが、変数ZはFORMAT「YYMMDD10」が付与されているので、外したくないものを避ける必要あり。
こんにちは。以前もご質問させていただきました。
返信削除importプロシジャでCSVファイルの読み込みをしたいのですが,
変数の数を指定する方法はありますでしょうか。
(66カラム目までを1行としたいのですが,実際は17行目から次の行へ移っています。)
宜しくお願い致します。
こんにちは、コメント有難うございます。
削除importプロシジャでは変数の数を指定する等細かい設定は出来ないと思います。
細かい設定をして読み込みたい場合は、データステップのinfile・inputを使うことになるかと思います。
>(66カラム目までを1行としたいのですが,実際は17行目から次の行へ移っています。)
実際のデータを見ないと原因の特定は難しいですが、大体以下が原因な事が多いです。
なのでまずはこれらを確認してみてください。
・データの中に見えない改行など、おかしなものがないか。
・記事中で紹介しているオプションで必要なものを全て指定しているか。
いつも大変勉強になる記事をありがとうございます。
返信削除2016年の記事ではありますが
proc importについてよく分からない動作があったため、質問させてください。
SAS9.3上でproc importを使ってcsvファイルを読み込む際に、
読み込み先の対象Folder内にある全てのcsvファイルを読み込むプログラムを組みました。
data _null_;
set WORK._CSV_Filename;
num=put(_n_,z2.);
call execute("PROC IMPORT");
call execute(" OUT=WORK._CSV"||strip(num));
call execute(" DATAFILE='&folder.\"||strip(filename));
call execute(" DBMS=CSV REPLACE;");
call execute(" GETNAMES=YES;");
call execute(" DATAROW=2;");
call execute(" GUESSINGROWS = MAX;");
call execute("RUN;");
run;
「WORK._CSV_Filename」はfilename変数に対象Folder内のファイルネーム(○○.csv)がレコード毎に格納されており、
&folder.には対象FolderのPassが登録されています。
問題としては、上記プログラムが問題なく流れてしまったことです。
状況としては、
call execute内でproc importを流すために全体を""もしくは''で囲いますが、
DATAFILE=のPass指定で''を使用したかったので、全体を""で囲っていました。
最後にDATAFILE=で''を使おうと思ったのですが、
マクロを使用するため、''を使うとマクロがマスクされてしまい流れないと考え、悩んでいたところ、間違えて上記プログラムの状態('が先頭にしか付いていない状態)でプログラムを実行してしまいました。
すると、上記プログラムは問題なく流れてしまい、
WORK上には想定通りのDatasetが出来あがり(_csvの後ろに数字が付いたDataset)、
Logには「DATAFILE='フルパス'」と後ろの'が補われた状態の結果が出てきてびっくりしました。(Error/Warningなし)
上記動作が通常動作なのかSASの自動補助機能なのか、不具合で起きた動作なのかわからず、ここに質問させていただきました。
ちなみに、(当たり前ではありますが)call execute外で上記を行うと、先頭'以降から次に発生する'まで全て文字値と判断され、proc importは動きません。call execute内で""で囲っているために起きた現象となります。
少しでも分かることがあればご教授いただければ幸いです。
よろしくお願い致します。
こんにちは、コメント有難うございます!
削除これ、知らなかったのですが、proc importではなく、call executeが引き起こしている事のようです。
例えば以下のように「a="abcd」として締めのダブルクォーテーションを書かないと、、
data _null_;
call execute( 'data test; a="abcd' );
call execute( ';run;' );
run;
以下のように勝手に締めのダブルクォーテーションが補完されて実行されました。
data test; a="abcd"
;run;
どうやら、勝手にクォーテーションを補完するのは、call executeの性質のようです。
リファレンスを読んでもこの事に言及されていなかったので、バグなのかなんなのか不明ですね。。
言及されてない以上は、バグだと思っていた方がいいかもしれません。
>matsu a さん
削除早急なご回答ありがとうございます!
Call executeの動作でしたか。。。
通常動作ではない以上、実装はしないようが良さそうですね。
ご丁寧な対応ありがとうございました。