見出し画像

SASの色々3

分析屋のH.Wです。
今回はSASでもできるけど、SQLを使った方が早いし便利なのに…
と思った部分を紹介します。

①レコード数をマクロ変数にするやり方

このデータセットを使用します。

data xxx;
input TRTAN SUBJID $20.;
cards;
1 001
1 002
1 003
2 004
2 005
;
run;

これは物凄く便利で、SQLが禁止ではない現場でよく使用しました。

proc sql noprint;
select count(*) into:cnt from xxx;
quit;

xxxというデータセットの中のレコード数がcntに入ります。
xxxのレコード数は5なので、cntというマクロ変数に5が入ります。

SASではマクロ変数を使う場合マクロ変数の前に&を入れます

data aaa;
cnt = &cnt.;
run;

データセットの中を見ると、マクロ変数cntの中身が5であることがわかります。

このようにwhereで条件を入れることもできます。

proc sql noprint;
select count(*) into:cnt from xxx where TRTAN = 1;
select count(*) into:cnt2 from xxx where TRTAN = 2;
quit;
data aaa;
cnt = &cnt.;
cnt2 = &cnt2.;
run;

それぞれのwhere条件に絞ってレコード数をマクロ変数に入れることができます。

これの何が便利かと言うと、集計表の割合を出力する部分で使いやすいです。(私の場合)

※使用例
data ae;
AETERM = "風邪"; COUNT =3; output;
AETERM = "頭痛"; COUNT =1; output;
run;

マクロ変数にしたあとで、直接分母として計算ができるのでとても楽でした。

data result;
set ae;
ratio = COUNT / &cnt. * 100;
run;

②マクロ変数をSASで使って不便に感じた部分

このデータセットを使用します。

data xxx;
input TRTAN SUBJID $20.;
cards;
1 001
1 002
1 003
2 004
2 005
;
run;

SASでマクロ変数を使う場合、「call symput」というものを使います。
さっきのSQL文と同じ感覚で「if文」を使ってコードを記述します。

data _null_;
set xxx;
if TRTAN = 1 then call symputx("cnt",_N_);
else if TRTAN = 2 then call symputx("cnt2",_N_);
run;
data aaa;
cnt = &cnt.;
cnt2 = &cnt2.;
run;


cnt2が5になってしまい、TRTAN=2のレコード数が正しく出力されません。
私の知っている限りでは、一回のデータステップで正しい処理が行えないので、ちょっと不便に感じました。
なので、レコード数をマクロ変数にする場合はSQLの方が楽だと思っています。

一応「where文」でも試してみましたが、結果は同じでした。

data _null_;
set xxx(in=a where=(TRTAN=1)) xxx(in=b where=(TRTAN=2));
if a then call symputx("cnt",_N_);
if b then call symputx("cnt2",_N_);
run;

③縦の合算をする場合

このデータセットを使用します。

data xxx;
input TRTAN SUBJID $ DOSE ;
cards;
1 001 2
1 002 2
1 003 1
2 004 3
2 005 1
;
run;

CRO業務でよくあるのですが、薬の投与量の合算をする場合があります。(ここでは変数DOSEが投与量とします)
そのときにSASだと「retain」や「transpose」などを使う場合がほとんどだと思います。

SQLだとこれだけで処理が終わるので、とても楽です。

proc sql noprint;
create table zzz as
select TRTAN, sum(DOSE) as alldose from xxx group by TRTAN;
quit;

上記のSQLコードの意味は
「データセット名xxxを使用してTRTANごとに変数DOSEの合算した値をalldoseという変数に入れて、データセット名zzzに出力する」
ということです。

TRTAN=1の総投与量が5、TRTAN=2の総投与量が4になっているので、正しく出力されています。

④SASのfirstやlastを使って縦の合算をする場合

data aaa(keep=TRTAN alldose);
set xxx;
by TRTAN;
if first.TRTAN then alldose = DOSE;
else alldose + DOSE;
if last.TRTAN then output;
run;

こちらでも同じように総投与量の合算ができますが、ステップ数が少し増えてしまいます。
慣れれば簡単なので、SQL禁止の環境で総投与量の合算をする場合はこのやり方でやっています。

このようにSQLを使用した方がSASを使用するより便利な場合もたくさんあるので、SASで使える便利なSQLが自由に使用できるような環境になるといいなと思います。

株式会社分析屋について

ホームページはこちら。

noteでの会社紹介記事はこちら。

【データ分析で日本を豊かに】
分析屋はシステム分野・ライフサイエンス分野・マーケティング分野の知見を生かし、多種多様な分野の企業様のデータ分析のご支援をさせていただいております。 「あなたの問題解決をする」をモットーに、お客様の抱える課題にあわせた解析・分析手法を用いて、問題解決へのお手伝いをいたします!
【マーケティング】
マーケティング戦略上の目的に向けて、各種のデータ統合及び加工ならびにPDCAサイクル運用全般を支援や高度なデータ分析技術により複雑な課題解決に向けての分析サービスを提供いたします。
【システム】
アプリケーション開発やデータベース構築、WEBサイト構築、運用保守業務などお客様の問題やご要望に沿ってご支援いたします。
【ライフサイエンス】
機械学習や各種アルゴリズムなどの解析アルゴリズム開発サービスを提供いたします。過去には医療系のバイタルデータを扱った解析が主でしたが、今後はそれらで培った経験・技術を工業など他の分野の企業様の問題解決にも役立てていく方針です。
【SES】
SESサービスも行っております。