2016年12月13日火曜日

グラフにしたいデータセットの欠測値のところでグラフをつなげないようにする話

データに欠測が無かったら、以下を実行するとグラフが出ますね。
(いまどきgplotかよとの指摘は今はご勘弁を…)
data hoge;
    a = 1; Y = 2; output;
    a = 2; Y = 3; output;
    a = 3; Y = 4; output;
    a = 4; Y = 5; output;
    a = 5; Y = 3; output;
    a = 6; Y = 7; output;
    a = 7; Y = 5; output;
    a = 8; Y = 8; output;
    a = 9; Y = 4; output;
run;
proc gplot data = hoge;
    plot Y * A ;
    symbol1 c = black V = dot I = join;
run;


もしデータに欠測があった場合、普通にやるとそこは線でつながります。
data hoge;
    a = 1; Y = 2; output;
    a = 2; Y = 3; output;
    a = 3; Y = 4; output;
    a = 4; Y = 5; output;
    a = 5; Y = 3; output;
    a = 6; Y = .; output;
    a = 7; Y = 5; output;
    a = 8; Y = 8; output;
    a = 9; Y = 4; output;
run;
proc gplot data = hoge;
    plot Y * A ;
    symbol1 c = black V = dot I = join;
run;




欠測のところで線を区切って欲しいときは、skipmissオプションを指定します
data hoge;
    a = 1; Y = 2; output;
    a = 2; Y = 3; output;
    a = 3; Y = 4; output;
    a = 4; Y = 5; output;
    a = 5; Y = 3; output;
    a = 6; Y = .; output;
    a = 7; Y = 5; output;
    a = 8; Y = 8; output;
    a = 9; Y = 4; output;
run;
proc gplot data = hoge;
    plot Y * A /skipmiss;
    symbol1 c = black V = dot I = join;
run;






















2016年12月6日火曜日

次のオブザベーションの値を持ってくる話

月一更新に落ち着いてきましたね。

次のオブザベーションの値を持ってくる方法にはいくつかあると思います。

元のデータと2オブザベーション目から読み込んだデータをマージしたりとか
hashで読みこんだりとかの方法が考えられます。
単純に次のレコードを持ってくるならsetステートメントのpointオプションを使う手もあります
グループ内での次のレコードを持ってくる、とかでしたらhashで読み込むのがよさげですが。

data hoge;
    a = 1; b = 6.0 ; output;
    a = 2; b = 3.0 ; output;
    a = 3; b = 4.0 ; output;
    a = 4; b = 2.0 ; output;
    a = 5; b = 5.0 ; output;
    a = 6; b = 1.0 ; output;
run;



data hoge2;
    set hoge end  = _last;
    _vnext = _n_ + 1;

    if _last = 0 then set hoge( keep = a rename = (a = next_a) ) point = _vnext;
        else call missing(next_a);                                              *-最終obsは次のレコードを持たない;

run;











これで変数aの次のオブザベーションの値を持った変数next_aが出来上がります。
今回は画像あげるテストも兼ねてたんですが大丈夫そうですね

2016年11月1日火曜日

文字の変数を数値に変換しつつ変数名は変えない話

タイトルの通り、何のひねりもない記事ですね
コードの通り、renameするだけです。

data hoge;

    AA = "123" ;

run;

data hoge2;
    set hoge;

    cchex = input(AA,best.);
    drop AA;
    rename cchex = AA;

run;

数値→文字もinputをputにすると大丈夫です。

2016年10月24日月曜日

小数点を残しつつ不等号を消して文字を数字にする話

数値を文字値にしたいときは往々にしてあると思います。
今回はそんなお話

文字値を数字にするときはinput(hoge,best.)かなんかで書くと思います。
ただ、不等号などの文字を消そうとするとき、うっかり小数点「.」まで消したこと、あると思います。
私だけですかね。

そんな時はcompressの第三引数を駆使すると何とかなります。

data hoge;
    AA = "11"  ; output;
    AA = "11.7"; output;
    AA = "25"  ; output;
    AA = "< 10"; output;
run;

data hogehoge;
    set hoge;
    BB = input( compress(AA , "." , "kd" ) , best.);
run;

compressは意外と便利です。

2016年9月29日木曜日

sasにもともと入ってるマクロの話

annotate macroの話です
毎度仕様を忘れて手こずるので書いときます
適宜追加するかもです

使うとき
%annomac;を宣言してあげます
これ書かないとマクロと認識してくれません

グラフとかに出力する場所の設定
  %system(3,3,3);
 *以降で指定する数字を百分率として扱います。画面を100%と見たときの割合で場所を指定できるようになります。
当然XとYに100を超える値を、これより下のannotate macroで指定したらERRORでます;


  %system(2, 3, 3);
 *以降で指定する数字は絶対値として扱います。グラフの軸の値に従って指定できるので便利です。;


グラフとかに文字を追加する

     %label(6    , 98  , "hogehoge"   , black,  0   , 0  ,  3.0   , 'MS Mincho',  5            ); 
 *%label(X,Y,"出力する文字列", 色   , 文字列の角度(0 - 360),文字の角度  , 文字size ,  font      , position(1-9) );

20161118更新_間違ってました。以下の数字以外は今度追加します
    /* positionについて
    4 = 中央   (右)
    5 = 中央   (真ん中)  標準値
    6 = 中央   (左)
    */
201611118更新ここまで


グラフとかに線を追加する
    %line( 1        , 30    ,  1       ,  28.5    , black , 1   , 0.15   ); 
   *%line(始点x , 始点Y , 終点X , 終点Y , 色    ,線種 ,線の太さ);
線種はいろんな数字を指定できます。1が実線で、あとは点線の具合が変わります。
線種はそこそこ多くの指定ができます。なんなら二桁とかもいけます。

仕様を忘れる筆頭のREPORTプロシジャとGPLOTプロシジャについても上げたいですね

2016年9月16日金曜日

文字の日付をSAS日付値にする

これもずいぶん手垢のついたネタですが、先日引っかかったので投稿します。

要は2015-12-04T05:00のようなデータをSAS日付値にする話です。

data hoge;
  AA = "2015-12-04T05:00";
   HOGET=input(AA,e8601dt.);
run;

とするだけの話です。
引っかかったのは元の文字の日付をほかのデータセットから読み込む時に
文字の前後にブランクでも入っていたのでしょうか
inputを実行したら、ERRORが出て通らなかったのですね。

最後は読み込んだ文字変数にstripを使って前後のブランクを取り除いたことで(?)inputが通りました。

いまだにいまいち原因がわかっていないのですが、とりあえず通ったのでよしとしています。
文字変数に欠測データもいなかったので、errorが出ると思っていなくてびっくりしました。


20160927更新

SAS9.4で実行したらERRORなくいきました。
日付値に秒が入っていないことがERRORの原因ぽいです。
それにしてもstripかますと動くことの説明にはなりませんが・・・・
SAS9.4なら秒が日付値に入っていなくても滞りなく動くみたいです。

20170510更新
spritではなくcatsを使ってもinputが通りました。
相変わらずこれの原因、解決策がわかりません

2016年8月21日日曜日

マクロクォーティングの話

恒例のマクロクォーティングの話ですね
いろんなところで書かれているのですが私も引っかかったので上げます

マクロ変数に格納するときには%nrstrとかで文字列をくくるとOKです
%let P = nrstr("&hoge");

call symputxを使うときは

data A;
    AA = "&hoge";
run;

data _null_;
    set A
    call symputx("P" , %nrstr(AA) );
run;
となります。

ここまではいいんですが、
マクロ変数から展開するときにクォートしたいときは
%superq()を使うことになります。

文字列をexcelに書いて、そのexcelをsasデータセットにして
マクロ変数に文字列を格納したい時に使いました。

文字列→(クォート処理)→変数→マクロ変数の時が%nrstr()関数
文字列→変数→(クォート処理)→マクロ変数の時に%superq()関数です

data _null_ ;
    call symputx("P" , ’ho&ge’);
run;

%put  %surperq(P);


で通ります

where文の条件分岐とかにマクロ変数を使う場合は
%superq()のほうが使いよいかもしれませんね。






2016年8月11日木曜日

repeat関数

指定した文字を指定した回数出力する関数。
構文は repeat("文字",n) です。
n+1回、指定した文字を出力します。
nには0以上の数しか入らないので、最低でも1回出力することになります。

x = repeat("hoge" , 2);
put x;

とすると
hogehogehogeと出力されます。


文字のところに" "とスペースも入れられます。
スペースの数をこの関数で制御して、
6 (  50.0)
7 (100.0)
2 (    2.0)
のように、めんどくさい桁そろえするときに重宝します。
あまり機会がないですが。

小数点の位置を揃える桁そろえのめんどくさいことめんどくさいこと

2016年7月27日水曜日

SAS9.3からsasemfでの出力が出来ない話

SAS9.3から、デフォルトのグラフの結果出力先がHTML形式になっています。
HTML形式の出力ですと、sasemfに対応していないため、
オプションを指定するとログにwarningが出ます。

これを回避するには
1、グラフをpngにする
2、9.2以前の様に出力先をLISTING形式にする
のどちらかになるかと思います。

2の出力先をLISTING形式にするには
ods _ALL_ CLOSE;
ods LISTING;
としてLISTING出力を有効にしてあげてください

どうもdeviceに限らず、goptionsステートメントの内容を有効にするには
LISTING出力である必要があるそうです。

2016年7月26日火曜日

freqはbyステートメントを空白指定しても通る話

freqプロシジャってbyステートメントを空白にしても通るんですね
byステートメントを書いたら、何かは指定しないとエラー出ると思ってました

データはSASのガイドから拝借しました

/*testデータ*/
data hoge;
    input Region Eyes $ Hair $ Count @@;
    label Eyes  ='Eye Color'
             Hair  ='Hair Color'
             Region='Geographic Region';
datalines;
1 blue    fair         23  1 blue  red     7  1 blue  medium 24
1 blue    dark       11  1 green fair   19  1 green red     7
1 green  medium 18  1 green dark   14  1 brown fair   34
1 brown red         5  1 brown medium 41  1 brown dark   40
1 brown black      3  2 blue  fair   46  2 blue  red    21
2 blue    medium 44  2 blue  dark   40  2 blue  black   6
2 green  fair         50  2 green red    31  2 green medium 37
2 green  dark        23  2 brown fair   56  2 brown red    42
2 brown medium 53  2 brown dark   54  2 brown black  13
;

以下は両方通る
*--byステートメントを空白指定----;
proc freq data=Color noprint;
   by ;
   tables eyes Hair Eyes*Hair / out=FreqCount outexpect sparse;
   weight Count;
run;

*--byステートメントに変数を指定------;
proc freq data=Color noprint;
   by region;
   tables eyes Hair Eyes*Hair / out=FreqCount outexpect sparse;
   weight Count;
run;

byステートメントに空白を指定した場合、byステートメントを書かなかったのと同じ結果になります。




2016年7月22日金曜日

ブログの始まり

某ユーザー会にて某氏に誘われたので始めました
某氏にいつまでばれないかを楽しみにしばらくは更新します
何を書くかについては特に決まった方針を立てないことにしております。
あまり縛りすぎると私は続かないので…