SAS Base Programming · 15-20%
構文エラーを直すだけでなく、実行はできたが結果が違うロジックエラーをログと検算で見抜く領域。
試験対策ハブ · 詳細項目
Mindset
SAS では、エラーが出なくても結果が間違っていることがあります。ERROR、WARNING、NOTE をすべて得点源として扱います。
Log Reading
1 つの構文ミスが、後続の行に複数の ERROR を連鎖させることがあります。ログを読むときは、最後のメッセージではなく、最初に異常が出た位置を優先します。
セミコロン欠落、引用符不一致、スペルミス、無効オプションなど、構文として実行できない原因を先に直す。
処理は続いても、上書き、切り詰め、形式不一致などで結果が崩れていないか確認する。
自動変換、未初期化変数、欠損値生成、入力行数や出力行数は、ロジックエラーの手がかりになる。
ログの obs 数、PROC FREQ、PROC MEANS、PROC PRINT(obs=) で、問題文の条件どおりに行が残っているか見る。
PUTLOG
PUTLOG は DATA ステップ中の値をログに出します。全件出すと読めないので、条件付きで絞るのが実務でも試験でも有効です。
by customer_id; は顧客ごとのグループ境界を使うための宣言。first.customer_id で累計を初期化し、SUM ステートメントで加算する。if customer_id = "C001" then do; は、確認したい ID だけにログ出力を絞る。putlog "DEBUG: " _n_= ...; は、反復回数と変数名つきの値をログに出す。data work.debug_total;
set work.orders_by_customer;
by customer_id;
if first.customer_id then total_amount = 0;
total_amount + amount;
if customer_id = "C001" then do;
putlog "DEBUG: " _n_= customer_id= order_date= amount= total_amount=;
end;
if last.customer_id then output;
run;
putlog _all_; は全変数を出せます。原因が見えないときの最終手段として便利ですが、ログが大きくなるため条件付きで使います。
_N_ は DATA ステップの反復回数、_ERROR_ はその反復でエラーが発生したかを示す一時変数です。ログ確認や条件付きデバッグで役立ちます。
Debug Patterns
ロジックエラーは、全行を眺めても見つかりません。疑わしい条件、特定 ID、グループの先頭・末尾など、原因が出そうな場面だけログに出します。
first.customer_id or last.customer_id は、グループの先頭・末尾だけをログに出す条件。first.customer_id= のように末尾に = を付けると、変数名と値を一緒に出せる。missing(amount) は欠損値を見つける条件。data work.debug_group;
set work.orders_by_customer;
by customer_id;
if first.customer_id then total_amount = 0;
total_amount + amount;
if first.customer_id or last.customer_id then
putlog "BOUNDARY: " _n_= customer_id= first.customer_id= last.customer_id= total_amount=;
if missing(amount) then
putlog "MISSING AMOUNT: " _n_= customer_id= order_date= amount=;
if last.customer_id then output;
run;
first. / last. が期待どおりの単位で立っているか確認する。Syntax
次の行まで 1 つのステートメントとして読まれ、後続に連鎖エラーが出る。
文字列が閉じられず、以降のコードが文字列扱いになる。
formt、legnth など。SAS は補正しない。
PROC やステートメントごとに使えるオプションが違う。
Common Notes
NOTE は「失敗」ではありませんが、結果を疑うべきサインを含みます。特に型変換、未初期化変数、欠損値生成は頻出です。
INPUT / PUT で明示変換へ直す。PROC CONTENTS と PUTLOG で変数名と値を確認する。Logic
ロジックエラーは、構文としては正しくても、結果が問題文と違う状態です。見つけるには、途中結果を小さく検算します。
PROC PRINT(obs=)、ログの obs 数、PROC FREQ で意図せず行が増減していないか確認する。
PROC CONTENTS で文字 / 数値、文字長、format を確認する。文字長不足は値の切り詰めにつながる。
WHERE と IF、日付定数、大小比較、欠損値の扱いを確認する。
first. / last. が意図した単位で立っているか、BY 変数とソート順を確認する。
Practice
自分で壊したコードを作り、ログから直す練習をします。試験前にこの作業をすると、ログを読む速度がかなり上がります。
set cert.orders の後にセミコロンがないため、次の if まで巻き込んで解釈される。amount = "1000" は、数値変数と文字リテラルの比較になり、自動変換の NOTE が出やすい。first.customer_id を使うには、事前ソートと DATA ステップ内の by customer_id; が必要。/* 意図的な練習: どこを直すべきかログで確認する */
data work.bad;
set cert.orders
if amount = "1000" then flag = 1;
if first.customer_id then total = 0;
total + amount;
run;
set 行のセミコロン。first.customer_id を使う前の by customer_id; とソート。