ラベル ステートメント: INPUT の投稿を表示しています。 すべての投稿を表示
ラベル ステートメント: INPUT の投稿を表示しています。 すべての投稿を表示

2018年3月16日金曜日

固定長のテキストファイルで、先頭スペースを保持して読み込む




以下のテキストファイルを読み込みたいとします。


C:\test\test.txt
0 .
1 a
2  b
3   c


*** 例①:失敗例 *****;
data TEST;
   length X 8. Y $3.;
   infile "C:\test\test.txt" truncover;
   input  X 1-1
             Y 3-5;
run;

  X  
  Y  
 0   
 1  a 
 2  b 
 3  c


文字変数Yには、テキストファイルの中身通り、先頭の半角スペースを保持して以下のように読み込みたかったのですが、ふつうに読み込むとこの半角スペースは消えちゃいます。

  X  
  Y  
 0   
 1  a 
 2   b 
 3    c



先頭の半角スペースを保持するには、以下のような工夫が必要です。
(後述しますが、文字欠損値の取り扱いだけ注意が必要)

*** 例② *****;
data TEST;
   length X 8. Y $3.;
   infile "C:\test\test.txt" truncover;
   input  @1 X
             @3 Y  $char3. ;
run;

  X  
  Y  
 0 
 . 
 1 
 a 
 2 
  b 
 3 
   c


「INPUT  @読み込み開始位置   変数名   $CHAR読み込む文字の長さ.」という感じで書きます。

  • 「@読み込み開始位置」で変数毎に読み込みを開始する位置を指定し、
  • インフォーマット「$CHAR」を使って先頭の半角スペースを切り捨てずに読み込んでいます
  • 「$CHAR」は文字変数として読み込むときに使います。上の例の変数Xは数値変数として読み込みたいので「$CHAR」は指定していません


注意
  • 文字欠損値の取り扱いだけ注意
    • 最初の例(例①)では、テキストファイルの1行目のドット「.」は欠損値として扱われて文字変数Yに読み込まれましたが、
    • 今回の例(例②)では、$CHARを使ったことで、テキストファイルの1行目のドット「.」がそのまま「.」という文字値として文字変数Yに読み込まれました。


その他の補足

今回の例で使用している「TRUNCOVERオプション」について知りたい方は、以下記事の最後らへんで解説しています。



2017年10月12日木曜日

「input &」で空白を含むテキストを1変数に読み込む



「INPUTステートメントで、半角スペース区切りで値を読み込む場合」の小技です。
以下の例をご覧ください。


data DT1;

length  JUICE $20.  YEN 8.;
input    JUICE &       YEN;

cards;
APPLE JUICE  120
ORANGE JUICE  130
;
run;



変数 JUICE の値が「APPLE JUICE」と「ORANGE JUICE」という感じで半角スペース(空白)を含んで読み込まれています。


ポイント

・INPUTステートメントで、変数の後に「&」を入れると、テキストに2つ連続する半角スペースが出てくるまでテキストを1つの変数に読込みます。
この機能は「&」を入れた変数のみに効力があります。


上のプログラムでは分かりづらいですが、
CARDSの中の「APPLE JUICE」と「120」の間には2つ半角スペースが入ってます。
同様に「ORANGE JUICE」と「130」の間にも2つ半角スペースが入ってます。



ちょっと前に紹介した以下の記事の方法もあわせて、状況によって使い分けましょう。
INPUTステートメントで、空白を含むテキストを1変数に読み込む方法


2016年4月7日木曜日

INPUTステートメントで、空白を含むテキストを1変数に読み込む方法


以下のようなテキストファイルがあったとします。

C:\TEST.txt
 SAS boubi roku
 I'm a.matsu


このファイルを読み込んで以下のデータセットを作りたいとする。
 TEXT  
 SAS boubi roku 
 I'm a.matsu



失敗例

data DT1;
    length TEXT $2000.;
    infile "C:\TEST.txt"  lrecl=32767;
    input TEXT;
run;
  TEXT   
 SAS
 I'm

テキスト中の半角スペース(空白)が区切り文字として解釈されるので文字が切れてしまいます。



解決案 : 自動変数 _INFILE_ を使う


解決案は色々ありますが、今回は自動変数 「_INFILE_」 を使ってみます。
(注意事項を追記したので、記事の最後までご覧ください)

data DT2;
    length TEXT $2000.;
    infile "C:\TEST.txt"  lrecl=32767;
    input ;
    TEXT = _infile_;
run;
 TEXT  
 SAS boubi roku 
 I'm a.matsu


解説
  infile "C:\TEST.txt"  lrecl=32767;

まず読込むテキストファイルを指定。
また「LRECL=」で1レコードに読み込める最大バイト数を指定しています。この設定値が小さいと文字切れの原因になるので、例では最大設定値(環境によって異なる可能性あり)の「32767」を設定。
それと、LENGTHも32767にしてしまうと、ファイルサイズが大きくなってしまうので、実データにあわせた長さに適宜設定します。


  input;

テキストファイルを1レコード読み込みに行きます。
ただしINPUTの後に変数の指定がないので、変数への出力はしません。


  TEXT = _infile_;

自動変数「_INFILE_」には入力バッファの内容が格納されています。
つまりテキストファイルから読込んだ1レコード分全文字が格納されています。
この文字を変数TEXTに代入すれば出来上がりです。


📝注意

テキストファイルで「先頭に半角スペースを含むレコード」がある場合は注意。
「今回の方法で変数に読み込んだら先頭の半角スペースが消えてしまった」とご報告頂きました。
私のほうでテストしたところ、問題なくスペースを保持することが出来ましたが、環境依存の可能性もあるので、各自の環境で挙動確認したほうが良さそうです。

ちなみに、ご報告頂いた内容とは別件かもですが、変数値の先頭に半角スペースがあっても、表示上、スペースが消えてみえることがあります。
例えばPROC PRINTで変数値を表示すると先頭の半角スペースが消えてみえます。
実際の格納値と異なるため、混乱のもとになりがちです。



関連記事
「input &」で空白を含むテキストを1変数に読み込む


2015年9月24日木曜日

「input @@」で外部ファイルの同じ行を読み続ける。



以下のようなCSVファイルがあったとします。

C:\TEST\SAMPLE.csv
aa,10,bb,20,cc,30
dd,40,ee,50


これを読み込んで以下のSASデータセットを作成したいとします。
 V1 
 V2 
  aa  
  10  
  bb  
  20  
  cc 
  30  
  dd  
  40  
  ee  
  50  


これはINPUTステートメントの最後に「@@」を追加してあげればok。
data DT1;
    length V1 $10. V2 8.;
    infile "C:\TEST\SAMPLE.csv" dlm="," dsd lrecl=32767;
    input V1 V2 @@;
run;


「@@」を入れることで、CSVファイルの同じ行を繰り返し読みに行くことができます。
読みにいくデータがなくなったら次の行に移動して、またその行を繰り返し読みに行く感じです。