私は神の掟に背いてSQLの中でLAG関数を使う

587 Views

April 03, 24

スライド概要

[第5回大阪sas勉強会]森岡裕

profile-image

SAS言語を中心として,解析業務担当者・プログラマなのコミュニティを活性化したいです

シェア

またはPlayer版

埋め込む »CMSなどでJSが使えない場合

関連スライド

各ページのテキスト
1.

外法SASプログラミング① -私は神の掟に背いてSQLの中でLAG関数を使う- 第5回 大阪SAS勉強会 森岡 裕

2.

LAGを使うのは未熟の証とか言われたり,業務で使 用禁止されている職場があったり,何かと嫌われる LAG関数 nオブザベーション前の指定変数の値を持ってくる のですが,Retainステートメントの方が制御がしや すいことや,後述する特殊な挙動により忌避される /*1obs前のageの値を代入*/ data wk1; set sashelp.class; lage=lag(age); run;

3.

例えば,年齢が15歳のときのみ,1obs前の値が欲しい と思って,LAG関数を使ったならば,それは間違い data wk1; set sashelp.class; if age=15 then lage=lag(age); run; LAG関数は正確には,1つ前にその関数を通過した値を 保持して返す関数だといえる それをわかって使うならOKよ

4.

1つ読み込んで,1つ出力するSASデータステップのシーケンシャルな処理を当て込んで,キューを構 築する関数なので, 本来,データの格納順からの解放を志向したSQLとは思想的に相容れない proc sql; select name,age,lag(age) as _age from sashelp.class; quit;

5.

エラーになるからって,「はいそうですか」なんてこの私が引き下がると思ったか? 無理だと言われれば,本当に無理か?と問うて突破してこそのSASプログラマだろ?

6.

これまた,いわくつきのmonotnic()関数(処理連番を取得,_N_に近いイメー ジ)を使って,自己参照結合でリレーションすれば,SQLでも1つ前の値をと れる proc sql; select BASE.NAME ,BASE.AGE ,PREV.AGE as _AGE from (select *,monotonic() as IND from sashelp.CLASS) BASE left join (select *,monotonic() as IND from sashelp.CLASS) PREV on BASE.IND=PREV.IND+1; quit; でも,そういうことじゃないんだよ!! 私はLAG関数を使いたいの!!!

7.

FCMPのSTATICステートメント使えるんじゃない?

8.

proc fcmp outlib=work.functions.common; function rsum(in); static x 0; B=in+x; x=B; return(B); endsub; run; options cmplib = work.functions; data TEST ; set sashelp.CLASS; sum_weight=rsum(weight); run ;

9.

data TEST ; set sashelp.CLASS; if SEX="F" then sum_weight=rsum(weight); keep name sex weight sum_weight; run ;

10.

LAG関数をFCMPで再定義してみる proc fcmp outlib=work.functions.common; function lagn(var); static st ; x=st; st=var; return(x); endsub; run; options cmplib = work.functions; data wk3; set sashelp.class; _age=lagn(age); run;

11.

年齢の値が体重にいっちゃってる でもSTATICは関数で,初期化されないということだから data wk1; set sashelp.class; _age=lagn(age); _weight=lagn(weight); keep name age weight _: ; run;

12.

まあ,1ステップ内で,1変数にしか使えないとかいう,酷い制限つきではあるけれど…

13.

proc sql; select name,age,lagn(age) as _age from sashelp.class; quit; SQLプロシジャ内でLAG関数もどきを実装できた

14.

最後にいつものやつ

15.

私は将棋は創作だと考えている。 何はともあれ、 一歩先に出た方が勝つ。 もし一局ごとに新手を出す棋士があれば、 彼は不敗の名人になれる。 その差はたとえ1秒の何分の一でもいい。 専門家というものは、 日夜新しい手段を発見するまでに 苦しまねばならぬ。 僕には 不利だ、不可能だといわれるものに 挑戦する性癖がある。 全部が全部成功するわけではないけれど、 それが新型になり、新手を生み、 つまり将棋の進歩に繋がる。 他の人は安全に先を考えるから 先輩の模倣を選ぶ。 - - 升田幸三 - 升田幸三 -