「色々な例数を簡単に出す」のデータステップ編です。
サンプルデータ
データステップで各例数を計算
解説
前に紹介した「SUMステートメント入門」と「1行プログラミング6:TRUE/FALSEを計算に利用する。」の合わせ技です。
応用
グループ毎に色々な例数や合計を出すこともできる。
たとえば、サンプルデータで以下のように「食品毎の例数や合計」を出したいとする。
データステップでグループ毎の例数や合計を出す。
解説
data DT1;
label FOOD = "購入食品"PRICE = "価格" EATFLG = "食べたフラグ" ; length FOOD $20.; input FOOD$ PRICE EATFLG; cards; ジュース 150 1 カップ麺 100 . ジュース 100 1 ジュース 200 . カップ麺 200 . ; |
求めたい結果
購入数 | ジュース購入数 | カップ麺購入数 |
---|---|---|
5 | 3 | 2 |
データステップで各例数を計算
data DT2; set DT1 end=EOF; /* ① */ C1 + (FOOD^="") ; /* ② */ C2 + (FOOD="ジュース") ; C3 + (FOOD="カップ麺") ; if EOF; /* ③ */ keep C:; run; |
解説
前に紹介した「SUMステートメント入門」と「1行プログラミング6:TRUE/FALSEを計算に利用する。」の合わせ技です。
- ① まず「end = 一時変数名」と書くと、最終行の一時変数に1が入ります。
- ② 条件式によって返される「1.true」「0.false」をSUMステートメントで合計していきます。
- ③ 最終的な合計がでる最終行のみを残します。
応用
グループ毎に色々な例数や合計を出すこともできる。
たとえば、サンプルデータで以下のように「食品毎の例数や合計」を出したいとする。
食品 | 購入数 | 合計金額 | 食べた食品の合計金額 |
---|---|---|---|
カップ麺 | 2 | 300 | 0 |
ジュース | 3 | 450 | 250 |
データステップでグループ毎の例数や合計を出す。
proc sort data=DT1; by FOOD; run; data DT3; set DT1; by FOOD; if first.FOOD then call missing(C1,C2,C3); /* ① */ C1 + (FOOD^=""); /* ② */ C2 + PRICE; C3 + (EATFLG=1)*PRICE; if last.FOOD; /* ③ */ keep FOOD C:; run; |
解説
- ① グループの各先頭行の時、計算結果を入れる変数を初期化する(call missingでNULLにする)
- ② SUMステートメントで合計していきます。
- ③ グループ毎の最終行のみを残します。
「C3 + (EATFLG=1)*PRICE;」のところの仕組みを補足しておくと、 (EATFLG=1) の条件が
- 「0.false」なら、C3 + 0*PRICEとなり、
- 「1.true」なら、C3 + 1*PRICEとなり、
「true/false」によって合計に含めるかどうかのトリガーにしています。
📝注意点
今回のテクニックの中で使用している「END=オプション」「FIRST.BY変数」「LAST.BY変数」は「サブセット化IF」と一緒に使用すると正しく動かなくなる事があります。
(解説記事:「サブセット化IFでありがちな落とし穴」)