以前、「ODS OUTPUTからデータセットを作る場合に複数変数を指定したプロシジャ出力の場合に(MATCH_ALL)で変数ごとにデータセットを自動連番で分けてもらう」という記事で
http://sas-tumesas.blogspot.jp/2014/02/ods-outputmatchall.html
ods outputの出力データセットを複数にわけるという話をしましたが、それに補足です。
data Q1;
X=1;Y=3;output;
X=4;Y=3;output;
X=6;Y=5;output;
run;
ods listing close;
ods output basicmeasures(match_all=MA)=AA;
proc univariate data=Q1;
var X Y;
run;
ods output close;
ods listing;
とmatch_allの後に=で任意の名前を指定すると、作成されたデータセット名がマクロ変数に格納されます。
実行後、
%put 作成されたのは &MA;
とすると
となります。
data OUTPUT;
set &MA;
run;
とすると、作成されたデータセットが対象となって縦連結されます。
じゃあなんでmatch_allつけて分けたの?って感じですが。
前回の記事では複数変数を指定したらという話でしたが
例えば
proc sort data=Q1;
by X;
run;
ods listing close;
ods output basicmeasures(match_all=MB)=BB;
proc univariate data=Q1;
var Y;
by X;
run;
ods output close;
ods listing;
のようにby変数ごとに結果のデータセットを作成した場合でも
%put 作成されたのは &MB;
とすると
となります。
作成されたデータセットに、マクロループなんかで同一の処理をかけたい場合に
役立ちます。
まあ今まで一度もそんな状況はなかったけど。
ODS OUTPUTからデータセットを作る場合に複数変数を指定したプロシジャ出力の場合に(MATCH_ALL)で変数ごとにデータセットを自動連番で分けてもらう
前の投稿に引き続きODS OUTPUTでデータセットを作る話ですが、前回の(PERSIST=PROC)と違って、今回(MATCH_ALL)については、僕はまだ実戦で使ったことはなくて、あんまりいい使いどころも見つけていません。
例えば、
data Q1;
X=1;Y=3;output;
X=4;Y=3;output;
X=6;Y=5;output;
run;
といったデータセットがあった場合
ods listing close;
ods output basicmeasures=A0;
proc univariate data=Q1;
var X Y;
run;
ods output close;
ods listing;
実戦で使ったことないのに、なんで自分はこの書き方知ってるんだろうと思って調べてみたら
2013年のSAS GLOBAL Forumの投稿で
「OUT= is on the way out. Use ODS OUTPUT instead」というPaperがあって、そこの中でのネタでした。
例えば、
data Q1;
X=1;Y=3;output;
X=4;Y=3;output;
X=6;Y=5;output;
run;
といったデータセットがあった場合
ods listing close;
ods output basicmeasures=A0;
proc univariate data=Q1;
var X Y;
run;
ods output close;
ods listing;
とするとvarで2変数指定していますが1プロシージャの出力なので、A0の中身は当然
XとYの要約統計量が両方入ります。
しかし、今度は、1変数ずつ、データセットを分けたいけど、複数回proc univariateは書きたくないなという願望があったとします。
その場合、
ods listing close;
ods output basicmeasures(MATCH_ALL)=AA;
proc univariate data=Q1;
var X Y;
run;
ods output close;
ods listing;
とすると
データセットAAと、AA1という2つのデータセットが作成され
それぞれにXとYの結果が入ります。
指定した変数の数だけ、勝手に末尾に自動連番して、データセットを作成してくれます。
実戦で使ったことないのに、なんで自分はこの書き方知ってるんだろうと思って調べてみたら
2013年のSAS GLOBAL Forumの投稿で
「OUT= is on the way out. Use ODS OUTPUT instead」というPaperがあって、そこの中でのネタでした。
on the way out.、 「(1) なくなりかけて, すたれかけて.」
なかなか、きついこといいますね。面白いです。
ODS OUTPUTからデータセットを作る場合に(PERSIST=PROC)で同系の出力を1セットにまとめる。あとODS TRACEの話も
たとえば
data Q1;
do X=1 to 20;
output;
end;
run;
data Q2;
do Y=1 to 10;
output;
end;
run;
という2つのデータセットがあるとします。
ods listing close;
ods output basicmeasures=A0;
proc univariate data=Q1;
var X;
run;
proc univariate data=Q2;
var Y;
run;
ods output close;
ods listing;
とするとデータセットA0の中身は
となり、つまりQ1に対してunivariateをかけた時のOutputしか捉えれていないです。
2つめのunivariateの結果をデータセットにしたければ、その直前に再度ods outputを打つ必要が
あります。
しかし
ods output basicmeasures(PERSIST=PROC)=A1;
proc univariate data=Q1;
var X;
run;
proc univariate data=Q2;
var Y;
run;
ods output close;
ods listing;
とすると
となって2つのODS出力が、ひとつのデータセットになります。
これは後で結果をデータステップで結合する必要がなくなったりして
しっていると結構便利です。
ちなみにODS出力の名前は
ods trace on;
proc univariate data=Q1;
var X;
run;
ods trace off;
としてods trace on offで挟んで対象プロシジャを実行すると、ログに
これの「名前」の部分を ods outputの後につけて、=作りたいデータセット名でOK。
もっと単純に
結果のところで、データセットにしたい部分をクリックして右クリック
「名前の変更」で
コピペできます。
data Q1;
do X=1 to 20;
output;
end;
run;
data Q2;
do Y=1 to 10;
output;
end;
run;
という2つのデータセットがあるとします。
ods listing close;
ods output basicmeasures=A0;
proc univariate data=Q1;
var X;
run;
proc univariate data=Q2;
var Y;
run;
ods output close;
ods listing;
とするとデータセットA0の中身は
となり、つまりQ1に対してunivariateをかけた時のOutputしか捉えれていないです。
2つめのunivariateの結果をデータセットにしたければ、その直前に再度ods outputを打つ必要が
あります。
しかし
ods output basicmeasures(PERSIST=PROC)=A1;
proc univariate data=Q1;
var X;
run;
proc univariate data=Q2;
var Y;
run;
ods output close;
ods listing;
とすると
となって2つのODS出力が、ひとつのデータセットになります。
これは後で結果をデータステップで結合する必要がなくなったりして
しっていると結構便利です。
ちなみにODS出力の名前は
ods trace on;
proc univariate data=Q1;
var X;
run;
ods trace off;
としてods trace on offで挟んで対象プロシジャを実行すると、ログに
これの「名前」の部分を ods outputの後につけて、=作りたいデータセット名でOK。
もっと単純に
結果のところで、データセットにしたい部分をクリックして右クリック
「名前の変更」で
コピペできます。
Create tableだけがSQLプロシジャでデータセットを作る方法ではないという話
今適当な、データセットがあったとします。
data Q1;
X=1;Y=2;output;
X=3;Y=4;output;
X=5;Y=6;output;
run;
そこで以下のSQLを実行すれば
proc sql noprint;
create table A1 as
select X
from Q1
where X<2;
create table A2 as
select X
from Q1
where X>2;
create table A3 as
select Y
from Q1;
quit;
data Q1;
X=1;Y=2;output;
X=3;Y=4;output;
X=5;Y=6;output;
run;
そこで以下のSQLを実行すれば
proc sql noprint;
create table A1 as
select X
from Q1
where X<2;
create table A2 as
select X
from Q1
where X>2;
create table A3 as
select Y
from Q1;
quit;
データセットA1,A2,A3が作成されます。
SQLプロシジャ内でcreate table データセット名 as 以下クエリを書けば
結果がデータセットになります。
SQLプロシジャでデータセットを作成するには上記のやり方しかないと思われている方も多いですが、そんなことはないです。
抜け道のようですが、SQLプロシジャはあくまでSASのプロシジャで、アウトプットを伴うプロシジャです。であれば、
ods listing close;
proc sql;
ods output SQL_Results=A1;
select X
from Q1
where X<2;
ods output SQL_Results=A2;
select X
from Q1
where X>2;
ods output SQL_Results=A3;
select Y
from Q1
;
quit;
当然、ODSの対象であり、ODSの対象であれば ods outputでデータセットにできるということです。
上記のコードで同じ結果を得ることができます。
これをどう活かすかを考えます。
例えばSASのデータステップでは
data A4 A5 A6;
set Q1;
if X=1 then output A4;
if X=2 then output A5;
if X=3 then output A6;
run;
のように一回のデータステップで、複数のデータセットを作れます。
しかし、create table文では、1回で同様の操作はできません(多分、、)
ですがODSを利用すれば
proc sql;
ods output
SQL_Results=A4(where=(X=1))
SQL_Results=A5(where=(X=3))
SQL_Results=A6(where=(X=5))
;
select X
from Q1
;
quit;
このように実現可能です。
また、データステップでは、call symput等で、データセットを作成すると同時に
何らかの値をマクロ変数に格納する処理も同時に行えます。
ですがSQLで同様のことを1文ではできません。
がODSを利用すれば
proc sql;
ods output SQL_Results=A7;
select X into:MX
from Q1
where Y=4;
quit;
のように、非常に幅の広いことができるようになります。
邪道といえば邪道かもしれませんが、せっかく、SASでSQLを使っているので
SASから利用できる部分はガンガン使っちゃっていいんじゃないでしょうか?
(DB内部やほかのシステムににSQL文を移植したりする予定がなければですが)
登録:
投稿 (Atom)








