基礎学習

【SAS】基礎05_外部ファイルの読み込み(FILENAME、INFILE、INPUTステートメント)

1. 外部データ

通常、SASを使って処理するためのデータが、最初からSASデータセットとして用意されることはない。SASとは別の、一定のフォーマットで入力されたデータファイル(ローデータ)として提供される。こうしたデータファイルのことをSASの用語では「外部ファイル(データ)」と呼ぶ。従って、通常は、外部ファイルを読み込んでSASデータセットを作成するという処理からスタートすることになる。
 


 

2. FILENAME、INFILE、INPUTステートメント

外部ファイルの読み込みで基本となるのは、下記3ステートメントである。

①FILENAMEステートメント
外部ファイルの物理的な保存場所に参照名を割り当てる。
※LIBNAMEステートメントの外部ファイル版と考えればよい

②INFILEステートメント
外部ファイルの属性に応じたオプションを指定する。

③INPUTステートメント
外部ファイルのデータ値をSASデータセットの変数に読み込む。

外部データを読み込むDATAステップの基本構造


FILENAME 参照名 "外部ファイルが保存されているフォルダのフルパス名";

DATA SASデータセット名;

	INFILE 参照名(外部ファイル名) オプション;

	INPUT
		変数の読み込み定義1
		変数の読み込み定義2
		・・・
	;

	その他のSASステートメント;
	その他のSASステートメント;
	・・・;

RUN;

FILENAME 参照名 CLEAR;

 

3. キャラクター(ASCII)形式データの読み込み

キャラクター形式の様な、すべてのデータがカラムで揃えられている固定長データを読み込む場合、INPUTステートメントでインフォーマットを使用する。この読み込み形式をSASではフォーマット入力と呼ぶ。

インフォーマット
データ値をSAS変数に読む込むときに指定する、カスタマイズされた読み込み指示のことをインフォーマットと呼ぶ。SASには、多種多様なインフォーマットが用意されている。処理するデータに応じたインフォーマットを指定するだけで、様々な形式のデータを適切にSAS変数に読み込むことができる。インフォーマットには、データ値を数値変数として読み込むための数値インフォーマットと、文字変数として読み込むための文字インフォーマットの2種類がある。

【INPUTステートメント(フォーマット入力)の基本形式】

INPUT
	ポインタ制御 変数名 インフォーマット
	ポインタ制御 変数名 インフォーマット
	・・・
;

【ポインタ制御】
・@nと指定した場合、カラムnに移動する。
・+nと指定した場合、nカラムだけ右に移動する。

【プログラム上でのインフォーマットの一般的な指定方法】
・[$]インフォーマット名W.で指定する。
・文字インフォーマットの先頭は「$」を付ける。
・Wは読込むフィールド幅を表し、最後にピリオド「.」を付ける。

多数あるインフォーマットのなかで、まずはキャラクター形式のデータ読み込みでよく使われる下記3種類を押さえておきたい。

①w.dインフォーマット
・標準的な数値データを読み込むときに使用する。
・wは32まで指定可能である。
・dは小数点以下の桁数を指定する。(例えば10.25が1025と入力されている場合4.2と指定)データ値に小数点そのものが含まれている場合、この指定は必要ない。

②$w.インフォーマット
・標準的な文字データを読み込むときに使用する。
・wは32767(文字変数の長さ上限)まで指定可能である。
・ローデータ上の前置(半角)ブランクは取り除かれて左詰めデータになる。

③$CHARw.インフォーマット
・前置ブランクを含む文字データを読み込む。
・w.インフォーマットとの違いは、ローデータ上の前置(半角)ブランクを含んだまま、データを読み込めることである。

 

【(外部ファイルじゃなくDATALINESで)固定長データを読み込む例】
data list_fixed;
	infile datalines;
	input
		@1  first_name  $10.	/*$w.インフォーマット*/
		@1  first_name2 $char10./*$CHARw.インフォーマット*/
		@11 last_name   $10.	/*$w.インフォーマット*/
		@11 last_name2  $char10./*$CHARw.インフォーマット*/
		@21 sex		1.	/*w.dインフォーマット*/
		@22 age		2.	/*w.dインフォーマット*/
	;
datalines;
     Kaori       Ito222
    Hideki    Tanaka135
      Taro    Yamada130
    Hiroki      Sato125
     Mizue     Ishii254
      Yuko    Koyama230
    Ichiro    Suzuki1
    Shinji      Suda127
     Reiko  Yamauchi242
    Mituru    Adachi345
;
run;

【実行結果】
list_fixed

first_name:「$w.インフォーマット」で読み込んでいるので、前置ブランクが取り除かれて、左詰めになっている。
first_name2:「$CHARw.インフォーマット」で読み込んでいるので、前置ブランクもそのままで、長さ10バイト分の変数値となっている。

 

4. カンマ区切り(CSV)・タブ区切り(TSV)形式データの読み込み

カンマ区切り(CSV)やタブ区切り(TSV)形式の様な、区切り文字を使用した可変長データの読み込みは、リスト入力と呼ばれるINPUTステートメントの入力形式でおこなう。変数名のみを羅列していくのが基本で、フォーマット入力に比べるとシンプルな記述形式である。

【INPUTステートメント(リスト入力)の基本形式】
INPUT 変数名 [$]

・文字変数の場合、変数名の後ろに$w.で長さを指定する。
・しかし、INPUTステートメントの前に、LENGTHステートメントで長さを指定している場合は不要である。

【リスト入力でインフォーマットを使用した場合の基本形式】
INPUT 変数名:インフォーマット 
・変数名の後ろに「:」を指定し、それに続けてインフォーマットを指定する

 

【事前準備】
「C:\Users」直下にカンマ区切りファイル「list.csv」が置いてあるとする。
list.csv

「list.csv」の中身は以下となる。
first_name,last_name,sex,age
Kaori,Ito,2,22
Hideki,Tanaka,1,35
Taro,Yamada,1,30
Hiroki,Sato,1,25
Mizue,Ishii,2,54
Yuko,Koyama,2,30
Ichiro,Suzuki,1,.
Shinji,Suda,1,27
Reiko,Yamauchi,2,42
Mituru,Adachi,3,45


【外部CSVファイルの読み込み例】
filename in "C:\Users";

data list_csv;

	infile in(list.csv) dlm="," lrecl=1000 firstobs=2 dsd missover;

	length
		first_name
		last_name
		$20.
	;

	input
		first_name
		last_name
		sex
		age
	;

run;


filename in clear;

【よく使用するオプション】
・DELIMITER(DLM)
区切り文字のことをデリミタといい、カンマ区切り(CSV)の場合は「dlm=","」、タブ区切り(TSV)の場合は「dlm="09"x」を指定する。CSVの場合、DSDオプションを指定していれば、デリミタの指定は省略しても良い。

・LRECL
CSVは可変長データなので、最も長いレコードの長さより大きい数字を指定する必要がある。LRECLの指定範囲は1~1000000であり、省略した場合はデフォルトの32676となる。
ちなみに、処理速度に関して、体感では1000でも1000000でも変わらなかったので、私が指定する場合は、大は小を兼ねるということで、1000000を指定している。

・FIRSTOBS
読み込みを開始する行数を指定する。CSVやTSVなどの可変長データの場合、1レコード目に変数名などが入っている場合が多いので、「firstobs=2」を指定することが多い。

・DSD
2つの連続する区切り文字を欠損値として扱うために使用する。また、データ値が引用符「''」や「""」で囲まれている場合、そのデータ値内の区切り文字を文字データとして扱うときにも必要となる。例えば、ダブルクォテーション「""」で囲まれた文字列「"Oh, year!"」の場合、真ん中のカンマ「,」を区切り文字としてではなく、文字データとして扱いたいときに指定する。

・MISSOVER
INPUTステートメントが、定義したすべての変数に対して、現在の入力行内に値を検出しなかった場合、新しい入力データレコードを読み込まないようにする。その際、値が格納されなかった変数は欠損値が格納される。

【実行結果】
list_csv

 

リスト入力時の文字変数の長さ
フォーマット入力で読み込んだ場合、作成される文字変数の長さはインフォーマットで指定された桁数によって決定される。一方、リスト入力を使うときはインフォーマットを指定しない場合も多いのだが、その場合SASが勝手に長さを8に設定してしまう。そうなると実際のデータ値の長さが8より大きい場合、9バイト目以降が切り捨てられてしまう。それを避けるために、リスト入力で文字変数を読み込む時は下記いずれかの方法を取る。

①LENGTHステートメントで長さを明示的に指定する。

【例】
length
	first_name
	last_name $20.
        sex
        age 8.
;

・一度に複数の変数を指定することができる。
・文字変数の場合は長さの前に「$」を付ける。
・文字変数の長さは「1~32767」の範囲で指定できるが、無駄に大きい値を指定すると、その分、メモリを浪費することになり、処理速度の低下を招く。
・この例ではあえて、数値変数を「8.」で指定したが、省略してもデフォルトの「8.」で読み込まれる。逆に、「8.」以外で読み込むと、予期せぬ計算誤差が生じる場合があるので、数値変数は基本的に「8.」以外に変更することは無い。

②コロン「:」を使用してインフォーマットを使用する。

【例】
input
	first_name:$20.
	last_name :$20.
	sex       :8.
	age       :8.
;