2018年4月4日水曜日

ルール間違ってた

「pandemic」というボードゲームにリベンジしてきました.
致命的なルールの勘違いをしていたことに気づいてしまいました.
4戦全敗した後でですが...
規則の確認を雰囲気でやってはいけない好例です.

このゲーム,ワクチンを作って病原菌を根絶(盤上から赤青黒黄の四色の駒を完全に取り除くこと)したら勝ちだと思っていたのですが,ワクチンを4種作った段階で勝ちなのですね.そら勝てないね.

ワクチンは一枚目の画像の版下部にある,なんか四角い四色の駒ですね.
一枚目の画像は赤のワクチン駒を獲得する前に時間切れで負けです.















2枚目は一応勝ちの状態です.盤下部に赤青黄黒の四角いワクチン駒を獲得できています.
しかしこれは参考程度です...手放しで喜べない勝ちなのです...
本来ランダムに決まるプレイヤの役職を,事前に選んでプレイしましたからね...
普通に勝利は次回に持ち越しですね...


2018年3月3日土曜日

グラフのラベルに改行を入れる話

SASでグラフを出す時に,軸のラベルや軸目盛の値の改行をするにはannotateをするしかない,と思っていました.
ところがどっこいaxisステートメントの指定の仕方で改行できるようです.
軸ラベルを改行させてほしいとリクエストが来るたびに,相手のことを呪っていたわけですが
これからはそんな呪いからも解放されますね.

sgplotで軸目盛のラベルの改行は出来たのですが,軸そのものへのラベルの改行のやり方が分からないのが次なる課題ですね...

/*---------- testデータ ----------*/

data hoge;
    call streaminit(11);
    do A=1 to 5;
        Y = int(rand('uniform') *10 );
        output;
    end;
run;

*---------- gplotでの場合 ;
proc gplot data = hoge;
    plot Y * A / vaxis = axis1 haxis = axis2 ;
    symbol1 c = black V = dot I = join;

    *---------- y軸目盛;
    axis1
      order = (0 to 5 by 1)
      origin=(10, 30)
      ;

    *---------- x軸目盛;
    axis2
      order=( 1 to 5 by 1 )
      origin=(10, 30)
      label=("x軸" j = c "ラベル")
      value=(tick = 1 "1" j = c "時間" j=c "経過"
             tick = 2 "2" j = c "時間" j=c "経過"
             tick = 3 "3" j = c "時間" j=c "経過"
             tick = 4 "4" j = c "時間" j=c "経過"
             tick = 5 "5" j = c "時間" j=c "経過"
            )
    ;
 run;

gplotでの出力イメージ












*---------- sgplotでの場合 ;
proc sgplot data = hoge  ;
    series x = A y = Y  ;

    xaxis
      type  = discrete
      fitpolicy=splitalways
      splitchar="*"
      label="x軸ラベル"
      values=(1 2 3 4 5)
      valuesdisplay=("1*時間*経過" "2*時間*経過" "3*時間*経過" "4*時間*経過" "5*時間*経過")
    ;   
run ;

sgplotでの出力イメージ

2018年2月19日月曜日

勝利を知りたい

この記事はsas関係ないです.ボードゲームです.

私趣味でボードゲームをたまにやるのですが,こないだぼこぼこに負けました.
「パンデミック」というプレイヤで協力して目的を達成するゲームがあるのですが,
そこでまあ見事に2戦2敗キメましたのでその供養です.

4人のプレイヤで協力して世界に蔓延る 4種類の病原菌を根絶することを目指すゲームです.詳しくは適当に調べてください.
私はそこで「ほかのプレイヤを動かせる」という固有の能力を持っていたのですが,あまり活用できませんでしたね…指定した離れた土地にプレイヤを一人ワープさせる力をもっと使いこなせていれば敗北とは違った結果が得られたかもしれません.

次やったときは確実に病原菌を根絶してくれよう覚悟してろ


敗北の盤面がこちら

2018年2月14日水曜日

割り算に欠測とか0が混ざってる時の話

割り算する時に,分子が0の時や分母が0とか欠測の時はどうなりますか,と聞かれました.

割った結果は何となくわかるのですが,logになんと出力されるのかが分からなかったので
実際に実行してlogを見たと言うだけの話です.

data DATA ;
    a = 1 ; b = 2 ; output ;
    a = 0 ; b = 2 ; output ;
    a = 1 ; b = 0 ; output ;
    a = . ; b = 2 ; output ;
    a = 1 ; b = . ; output ;
run ;

data DIVISION ;
    set DATA ;
    c = a / b ;
run ;


実行log





結果















分母が0の時は,0による割り算がありましたってnoteが出ていますね.
欠測がどっちかに入っている時は,欠測値を含んだ計算により...と言うよく見るやつが出ています.
その下の以下の箇所で演算式を計算できなかった...と言うのは0による割り算に対して出ています.
分子が0で分母に数が入っている場合は,結果が0として出ます.









2018年1月27日土曜日

SASオフ会に行ってきました

露骨にブログ記事を稼いでいくスタイルを見せつけています.
特に内容はないです.

先日(1月26日)にデータステップ100万回の管理人さん含めて6人でオフ会しました
せっかくの飲み会…ということで一人一つsasネタを持ち寄って軽く紹介しあいました
ユーザー会より気楽にネタ作ってポンと発表できるのはいい感じでしたね…

私が持って行ったネタの資料はswayに転がしておきました
こちらから閲覧できます.
pptの資料をswayに変換しただけなのでイマイチ見にくいかもしれません

次の開催は4月か5月頃ですかねえ.年度末は忙しいですし.

2018年1月25日木曜日

Wilcoxonの符号付き順位和検定_proc univariate

SASでWilcoxonの符号付き順位和検定は,proc univariateを実行することで出来ます.
こちらはWilcoxonの順位和検定と異なり,対応のあるデータに対して行います.

univariateプロシジャに,対応前後の差の値(変化量の様なもの)を格納した変数を指定します.
以下の仮のデータセットで言う所の「CHG」に当たります.(after-beforeで導出)

以下のプログラムではTEST_UNIのデータセットにunivariateプロシジャの結果を出力しています.
Wilcoxonの順位和検定のp-値は「_PROBS_」に格納されています.

今回はnoprintを指定することでoutput画面への出力を抑制していますが,
outputでは「位置の検定」の項目に結果が出されています.


/*---------- プログラム ----------*/

data TEST ;
 CAT = 1 ;  BEFORE = 1 ; AFTER = 3 ; CHG = 2  ; output ;
 CAT = 1 ;  BEFORE = 2 ; AFTER = 6 ; CHG = 4  ; output ;
 CAT = 1 ;  BEFORE = 3 ; AFTER = 1 ; CHG = -2 ; output ;
 CAT = 1 ;  BEFORE = 4 ; AFTER = 3 ; CHG = 1  ; output ;
 CAT = 2 ;  BEFORE = 5 ; AFTER = 2 ; CHG = -3 ; output ;
 CAT = 2 ;  BEFORE = 6 ; AFTER = 1 ; CHG = -5 ; output ;
 CAT = 2 ;  BEFORE = 7 ; AFTER = 6 ; CHG = -1 ; output ;
 CAT = 2 ;  BEFORE = 8 ; AFTER = 5 ; CHG = 3  ; output ;
run ;

proc univariate data = TEST outtable = TEST_UNI noprint ;
 class CAT ;
    var CHG  ;
run ;

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>