2017年12月13日水曜日

SASの処理は1obsごとに行われていると言う話

これは私のプログラム力が低いと言う話です.
何を今更こいつ......となるかもですが,そこはそっとしてあげてください

data DAT1 ;
    a = 1 ; n = 10 ; output ;
    a = 3 ; n = 20 ; output ;
    a = 4 ; n = 30 ; output ;
    a = 6 ; n = 50 ; output ;
run ;

これまで上のデータセットから,a=1の時のnの値をマクロ変数に入れる時は
「if a = 1 then call symputx("_all1" , N)」と書いていたわけです.
同様にa = 2 の時のNを格納したマクロ変数を作る時は,
「if a = 2 then call symputx("_all2" , N)」と書いていました.

これって1つとか2つとかならいいんですが,3つ4つとマクロ変数を作らないといけない時は
下の様にif文をいっぱい書いていたわけです.ほんと無駄ですね.

data _null_ ;
    set DAT1 ;

    *---------- Aの値毎にマクロ変数作る時にif文で分岐させてた ;
    if A = 1 then call symputx("_all1" , N)
    if A = 3 then call symputx("_all3" , N)
    if A = 4 then call symputx("_all4" , N)
    if A = 6 then call symputx("_all6" , N)

    *---------- 同じことが1行で書けちゃう ;
    call symputx( cats("_all" , A) , N) ;

run ;

別に1obsごとに実行するのはマクロ変数作る時だけではないです.…今更ですね

data MOLEC ;

    A = 1 ; COUNT = 5 ;  output ;
    A = 3 ; COUNT = 10 ; output ;
    A = 4 ; COUNT = 20 ; output ;
    A = 6 ; COUNT = 11 ; output ;

run ;

data HOGE ;
    set MOLEC ;
   
    *---------- 今まではifで分岐させてマクロ変数を指定して割り算していた ;
    if A = 1 then OUT = round(COUNT / &_all1 , 1e-08) ;
    if A = 3 then OUT = round(COUNT / &_all3 , 1e-08) ;
    if A = 4 then OUT = round(COUNT / &_all4 , 1e-08) ;
    if A = 6 then OUT = round(COUNT / &_all6 , 1e-08) ;

    *---------- 同じことが1行で書けちゃう ;
    OUT2 = cats(COUNT / symgetn( cats("_all", A) ) , 1e-08) ;

run ;

いやー自分のスキルのなさが恥ずかしい

あ,いまさらツイッタ始めました
<https://twitter.com/dap123586>