SAS Base Programming · 20-25%

データ構造へのアクセスと作成

ライブラリを割り当て、既存データを読み、外部ファイルを取り込み、結合し、日付や行列制御まで扱う領域。

試験対策ハブ · 詳細項目

Goal

この項目で到達する状態

問題文にある入力元を見て、SAS データセットとして読み込み、必要な行・列・型に整えて、次の処理へ渡せる状態を作ります。

01

一時・永久データセットとライブラリ

SAS データセットは、セッション中だけ使う一時データセットと、ファイルとして残す永久データセットに分かれます。work ライブラリに作るものは一時、cert.sales のように自分で割り当てたライブラリに作るものは永久です。

ライブラリを割り当てる — LIBNAME

基本形: libname ライブラリ名 "フォルダのパス";

指定したフォルダに、SAS プログラム内で使うライブラリ名を割り当てます。

/* フォルダに cert というライブラリ参照名を割り当てる */
libname cert "/home/user/cert";

一時データセットを作る — DATA

基本形: data work.データセット名;

省略形: data データセット名;

ライブラリ名を省略した場合も、自動的に work ライブラリへ作成されます。どちらも一時データセットのため、SAS のセッションを終了すると削除されます。

/* WORK を明示する書き方 */
data work.sales_temp;
  set cert.sales_raw;
run;

/* ライブラリ名を省略しても WORK に作られる */
data sales_temp;
  set cert.sales_raw;
run;

永久データセットを作る — DATA

基本形: data ライブラリ名.データセット名;

指定したライブラリ内に永久データセットを作成します。ライブラリが参照するフォルダにファイルとして残ります。

/* cert ライブラリに永久データセットを作る */
data cert.sales_clean;
  set work.sales_temp;
run;

既存データセットを読み込む — SET

基本形: set ライブラリ名.データセット名;

指定した既存の SAS データセットを読み込みます。読み込んだ行を DATA ステップで処理し、新しいデータセットへ出力します。

/* 既存の sales_raw を読み込む */
data work.sales_temp;
  set cert.sales_raw;
run;

データセットの構造を確認する — PROC CONTENTS

基本形: proc contents data=ライブラリ名.データセット名;

指定したデータセットの変数名、型、長さ、format などの構造を確認します。

/* データセットの構造を確認する */
proc contents data=cert.sales_clean;
run;

何が表示されるか

データセット名  CERT.SALES_CLEAN
オブザベーション数  250
変数の数             4

番号  変数名       タイプ  長さ  出力形式     ラベル
1     customer_id  文字       8               顧客ID
2     sale_date    数値       8  YYMMDD10.    売上日
3     amount       数値       8  COMMA12.2    売上金額
4     region       文字      12               地域

出力項目の意味と確認事項

表示項目意味確認すること
データセット名対象のライブラリ名とデータセット名調べたいデータセットが選ばれているか
オブザベーション数データの行数行数が想定どおりか。違う場合は抽出条件や重複を確認する
変数の数データの列数必要な変数の不足や、不要な変数の混入がないか
タイプ変数が文字型か数値型か計算する値や SAS 日付などが想定した型になっているか
長さ変数に保存できる長さ文字型の長さが十分か。値が途中で切れる可能性がないか
出力形式値を画面やレポートに表示する形式YYMMDD10. など、意図した表示形式が設定されているか
ラベル変数名とは別に設定する表示用の説明レポートに表示する説明が正しいか

確認テスト

問題 1. data sales; で作成されるデータセットはどれですか。

問題 2. PROC CONTENTS の出力で確認できないものはどれですか。

問題 3. フォルダに cert というライブラリ名を割り当ててください。

 cert "/home/user/cert";

問題 4. sales_temp を一時データセットとして作成してください。

data .sales_temp;
  set cert.sales_raw;
run;

問題 5. 既存の cert.sales_raw を読み込んでください。

data work.sales_temp;
   cert.sales_raw;
run;

02

CSV・Excelファイルを読み込む

外部ファイルをSASデータセットへ変換します。読み込みに成功しても型や長さが意図と異なることがあるため、作成後の確認までを一連の操作として覚えます。

CSVファイルを読み込む — PROC IMPORT

基本形: proc import datafile="ファイルのパス" out=出力先 dbms=csv replace;

DATAFILE= に入力ファイル、OUT= に作成するSASデータセットを指定します。DBMS=CSV はファイル形式、REPLACE は同名データセットの上書きを表します。

GUESSINGROWS= は、各列のタイプと長さを推測するために確認する行数を指定します。guessingrows=max; は全行を確認する指定で、後半に長い文字列や異なる形式の値がある場合の文字切れや誤った型推測を防ぎやすくなります。ただし、大きなファイルでは読み込みに時間がかかります。

GUESSINGROWS はCSVなどの区切りファイル向けで、XLSXエンジンには使いません。

/* CSVをWORK.ORDERSとして読み込む */
proc import datafile="/home/user/source/orders.csv"
            out=work.orders
            dbms=csv
            replace;
  guessingrows=max;
run;

Excelブックをライブラリとして開く — XLSXエンジン

基本形: libname ライブラリ名 xlsx "Excelファイルのパス";

Excelブックを一時的なライブラリとして割り当てます。シート名をデータセット名として SET で読み込み、使用後は libname ライブラリ名 clear; で割り当てを解除します。

/* Januaryシートを読み込む */
libname excel xlsx "/home/user/source/orders.xlsx";

data work.orders_january;
  set excel.January;
run;

/* Excelブックのライブラリ割り当てを解除する */
libname excel clear;

読み込み結果の先頭行を確認する — PROC PRINT

基本形: proc print data=ライブラリ名.データセット名(obs=行数);

OBS= を指定すると、先頭から表示する行数を制限できます。値の並び、欠損、文字切れ、日付の見え方を少量のデータで確認します。

/* 先頭10行だけ表示する */
proc print data=work.orders(obs=10);
run;

出力例

Obs  customer_id  order_date  amount  region
  1  C001         2026-01-05   12500  East
  2  C002         2026-01-06    8300  West
  3  C003         2026-01-06       .  North
  4  C004         2026-01-07   21000  East

出力項目の意味と確認事項

表示項目意味確認すること
Obs表示上の行番号指定した行数まで表示されているか
各変数の値読み込まれた実際のデータ欠損、文字切れ、桁ずれがないか
日付の表示日付変数に適用された表示形式文字列のまま、または数値の連番になっていないか

確認テスト

問題 1. PROC IMPORTOUT= で指定するものはどれですか。

問題 2. CSVを work.orders へ読み込む構文を完成させてください。既存の同名データセットは上書きを許可し、全行を確認して列のタイプと長さを推測してください。

proc import ="/home/user/source/orders.csv"
            =work.orders
            =csv
            ;
  =max;
run;
問題 3. guessingrows=max; の意味はどれですか。

問題 4. Excelブックをライブラリとして割り当てる構文を完成させてください。

libname excel  "/home/user/source/orders.xlsx";

問題 5. Excelの January シートを読み込む構文を完成させてください。

data work.orders_january;
   excel.January;
run;

問題 6. excel のライブラリ割り当てを解除する構文を完成させてください。

libname excel ;

問題 7. work.orders の先頭10行を表示する構文を完成させてください。

proc print data=work.orders();
run;

03

データセットを縦・横に結合する

同じ列構造のデータを行方向に追加するときは SET、共通キーを使って列方向に結合するときは MERGE ... BY を使います。

複数のデータセットを縦に連結する — SET

基本形: set データセット1 データセット2 ...;

SET に複数のデータセットを並べると、記述した順番で行が追加されます。月別データなど、列構造が同じデータの統合に使います。

/* 3か月分の売上を縦に連結する */
data work.all_sales;
  set cert.sales_jan cert.sales_feb cert.sales_mar;
run;

結合キーの順番に並べる — PROC SORT

基本形: proc sort data=入力データ out=出力データ; by キー変数; run;

MERGE ... BY を実行する前に、すべての入力データセットを同じBY変数の順番でソートします。

/* 2つのデータを同じキーで並べる */
proc sort data=cert.customers out=work.customers;
  by customer_id;
run;

proc sort data=work.all_sales out=work.sales_sorted;
  by customer_id;
run;

共通キーで横に結合する — MERGE / BY

基本形: merge データセット1 データセット2; by キー変数;

同じBY変数の値を持つ行を1行にまとめ、列方向に結合します。入力データセットは事前にBY変数でソートされている必要があります。

/* customer_idをキーに顧客情報を付ける */
data work.sales_with_customer;
  merge work.sales_sorted work.customers;
  by customer_id;
run;

結合元に応じて行を残す — IN=

基本形: merge データセット1(in=フラグ1) データセット2(in=フラグ2);

IN= は、そのBYグループが各入力データセットに存在したかを示す一時フラグを作ります。両方にある行だけ残す場合は、2つのフラグを AND で結びます。

/* 両方に存在するcustomer_idだけ残す */
data work.matched_sales;
  merge work.sales_sorted(in=in_sales)
        work.customers(in=in_customer);
  by customer_id;
  if in_sales and in_customer;
run;

条件の意味と残る行

条件意味残る行
if in_sales;売上側を基準にする売上に存在するすべてのキー
if in_customer;顧客側を基準にする顧客マスタに存在するすべてのキー
if in_sales and in_customer;両方にある行だけにする双方に存在するキー

確認テスト

問題 1. 月別データを縦に連結するときに使う構文はどれですか。

問題 2. 結合キーを指定する構文を完成させてください。

merge work.sales work.customers;
 customer_id;
run;

04

必要な行・列を選び、日付を扱う

入力時に必要な行と列だけを読み込み、文字列の日付をSAS日付値へ変換します。値の保存方法と表示方法は別に考えます。

読み込む列を限定する — KEEP=

基本形: set データセット名(keep=変数1 変数2 ...);

KEEP= はデータセットオプションです。DATAステップへ読み込む前に、必要な列だけに限定します。

/* 3列だけ読み込む */
data work.orders_selected;
  set work.orders(keep=customer_id order_date_char amount);
run;

読み込む行を条件で限定する — WHERE

基本形: where 条件式;

WHERE は入力データセットにすでに存在する変数を使い、DATAステップへ読み込む行を限定します。DATAステップ内で新しく作った変数は条件に使えません。

/* amountが0より大きい行だけ読み込む */
data work.positive_orders;
  set work.orders;
  where amount > 0;
run;

文字列をSAS日付値へ変換する — INPUT

基本形: 新しい変数 = input(文字変数, informat.);

INPUT 関数は、文字値を指定したinformatで読み取り、数値へ変換します。日付文字列には、その並びに合う日付informatを指定します。

/* 2026-08-29という文字列をSAS日付値へ変換する */
data work.orders_dates;
  set work.orders;
  order_date = input(order_date_char, yymmdd10.);
run;

新しく作った値で行を限定する — IF

基本形: if 条件式;

サブセット化IFステートメントは、DATAステップで処理した後に出力する行を限定します。INPUT で作った日付変数なども条件に使えます。

/* 変換後の日付が2026年以降の行だけ残す */
data work.orders_2026;
  set work.orders;
  order_date = input(order_date_char, yymmdd10.);
  if order_date >= '01JAN2026'd;
run;

値の表示形式を設定する — FORMAT

基本形: format 変数名 format.;

FORMAT は保存されている値を変えず、表示方法だけを設定します。SAS日付値に YYMMDD10. を設定すると、年月日の形式で表示されます。

/* SAS日付値を2026-08-29の形で表示する */
format order_date yymmdd10.;

出力から不要な列を除く — DROP

基本形: drop 変数1 変数2 ...;

DROP ステートメントは、DATAステップが出力するデータセットから指定した変数を除きます。

/* 変換元の文字変数を出力しない */
data work.orders_2026;
  set work.orders;
  order_date = input(order_date_char, yymmdd10.);
  format order_date yymmdd10.;
  drop order_date_char;
run;

構文の役割と使うタイミング

構文役割使うタイミング
KEEP=読み込む列を限定する入力前
WHERE既存変数の条件で行を限定する入力時
IF処理後の条件で出力行を限定するDATAステップ内
DROP出力から列を除く出力時
FORMAT値の表示方法を設定する表示時

確認テスト

問題 1. INPUT で新しく作った order_date を条件に行を残す構文はどれですか。

問題 2. 文字列をSAS日付値へ変換する関数を入力してください。

order_date = (order_date_char, yymmdd10.);

問題 3. 出力から order_date_char を除く構文を完成させてください。

 order_date_char;

Practice

この項目の演習

CSV と Excel を読み込む

読み込み後に PROC CONTENTSPROC PRINT(obs=10) を実行し、型と日付表示を確認する。

月別売上を連結する

3 つの月別データを SET で縦結合し、件数を検算する。

顧客マスタをマージする

売上と顧客マスタを customer_id でソートし、MERGE ... BY で結合する。

必要な行と列だけにする

日付変換、金額条件、列制御を入れて、最終データセットを作る。