省略の極み data;set;run; _LAST_

data A;
 X=1;
run;

data;
 set;
 X=X+1;
run;


上記のコードを実行するとどうなるでしょうか?

2ステップ目はdataの後も何もなく、setの後にも何も指定していません。

結果は









こんな感じになります。

dataで何も指定しないと、勝手に連番でDataXXといったデータセットが実行の度に作成されます。

これについては以前、「どうてもいい話 データセット名をかかずに実行」

で触れていました。完全に忘れていましたが、、。

で、今回はsetで何も指定しないとどうなるかという話で、これは

自動的に

set _LAST_;として解釈され、実行されます。

例えばプロシジャの指定で
proc print;
run;

として実行した場合も

proc print data=_LAST_;
run;

と自動で解釈されて実行されます。

で、この_LAST_ってなにって?なると、直前に作成されたデータセットが自動的に指定されます。


なので、最初のコードで、勝手にDATA1とか作るのではなくデータセットAを上書きしたいんだという場合は


data A;
 X=1;
run;

data _LAST_;
 set;
 X=X+1;
run;

とすれば








って感じです。


_LAST_は使いどころ無くはないです。
マクロの中とかで、データセットの作成順に変わる余地がない場合とか?

それでも、あてにしていたステップでデータセットが作成されず、想定外のものを_LAST_で拾ってしまう可能性もあるので、僕はあまり使ったことないですが。





人真似をして結局失敗。飛び値がある場合の、数字→文字変換

リンクサイト「SAS忘備録」の記事「1行プログラムその3:数値を任意の文字に置き換える。」
http://sas-boubi.blogspot.jp/2014/03/13.html

を読んで、やっぱ凄いなぁと思いました。

で、記事の最後の方で、飛び番の場合は注意とありました。

実際、1='あり' 2='なし' 100='不明'というような変換が必要な場合ってよくあります。

if文とかselect文、或いはフォーマット作ってからそれを当てる以外に書き方ないかなぁと考えました。

data DT1;
 input V1;
 cards;
 1
 100
 2
 999
 ;
 run;









data DT2;
 array A{999} $10.;
  A{1}='なし';
  A{2}='あり';
  A{100}='不明';
  A{999}='もっと不明';
 set DT1;
  if V1^=. then V2=choosec(V1,of A{*});
 keep V1 V2;
run;







おっ、これならchoosec使えんじゃない?と思ったけども

それなら


data DT3;
 array A{999} $10.;
  A{1}='なし';
  A{2}='あり';
  A{100}='不明';
  A{999}='もっと不明';
 set DT1;
  if V1^=. then V2=A(V1);
 keep V1 V2;
run;


これでいいし、そもそもこんなにだらだらコードがかさむなら、if文と変わらないし、
全然1行コードから離れるし、駄目でした。


第3回電王戦の第二局を観覧しに行きます。

完全に趣味の話です。

将棋プログラムや囲碁プログラムが好きです。
将棋も囲碁も現在の思考アルゴリズムは、乱暴に言うとプロ棋士の対局のデータベースを読み込んで、とりうる指し手をそれぞれ得点化する関数を作成し、その関数がはじき出す、高得点な手を指し続けることで勝つ感じです。

またモンテカルロ囲碁という言葉を聞いたことがある方も多いと思いますが、ここ最近の囲碁プログラムの発展は目覚ましく、そのきっかけは2006年にフランスの方がモンテカルロ法を導入したことがきっかけになっています。(モンテカルロ法の囲碁への応用が最初に提案されたのは93年です)


で、先週の3/15日から毎週土曜日に5週連続で、コンピュータプログラム対プロ棋士の戦いが行われています。

その第2戦目を3/22観戦にいきます。

http://ex.nicovideo.jp/denou/

もし、このブログを見られている方の中に、同じく観戦にいかれる方がいれば、ご連絡ください。
SASと将棋を一緒に話せる人を探してます。

あと、SASで将棋や囲碁の思考プログラムを組まれている方がいらっしゃれば、同じくご連絡いただけると幸せです。

データステップ100満開 文字列がどれくらい類似しているかを定量化する

「データステップ100満開」という検索ワードでこのブログが検索されていて、春めいていて素敵だなぁと思いました。

「データステップ100満開」と「データステップ100万回」ってどれぐらい似てるでしょうか?検索で出てくるわけだから、まあ似てるんでしょう。
その似てるさ度合いを数値化してみます。
(Googleとかの検索アルゴリズムは、類似度だけじゃなく事前情報をつかって、なんか統計的な凄いことしてるんでしょう。僕はわかりません)


文字列がどの程度類似しているかを定量化する術は多く研究化されています。僕は全く門外漢なので、さわりだけ。
有名なのが編集距離の概念で、ようはどれぐらい操作を加えたら一致するのかで考え、操作の回数やコスト(1文字替えて一致するなら100ポイントみたいな)合計でもって、似てるっぽさをだそうという感じです。

明らかアルファベットで構成される言語に向いてそうですが、まあそこは置いておいて。

data Q1;
length X Y $50.;
X='データステップ100万回';Y='データステップ100満開';output;
X='データステップ100万回';Y='データステップ1万回';output;
X='データステップ100万回';Y='デデデータステップ100万回';output;
X='データステップ100万回';Y='出た!ステップ100万買い';output;
X='ABC';Y='ABC';output;
X='ABC';Y='AABC';output;
X='ABC';Y='AB';output;
X='ABC';Y='ABD';output;
X='ABC';Y='CAB';output;
X='ABC';Y='AAA';output;
X='ABC';Y='XYZ';output;
X='ABC';Y='ABCABC';output;
X='ABC';Y='A B C';output;
run;

こういうデータがあったとします。

それに3つの関数をかけてみます

data A1;
set Q1;
SP=SPEDIS(X,Y);
CG=COMPGED(X,Y);
CLV=COMPLEV(X,Y);
run;











SPEDIS関数のスコア計算の基準
http://support.sas.com/documentation/cdl/en/lrdict/64316/HTML/default/viewer.htm#a000245949.htm

COMPGED関数のスコア計算の基準
http://support.sas.com/documentation/cdl/en/lrdict/64316/HTML/default/viewer.htm#a002206133.htm

COMPLEV関数のスコア計算の基準
http://support.sas.com/documentation/cdl/en/lrdict/64316/HTML/default/viewer.htm#a002206137.htm

だいたい同じ傾向ですが、微妙な順序の違いが面白いですね!



ODS PDFでしおりの名前を自由に設定する  proclabelやproc printのcontents pageby等

ODSを使えば、いろんなファイル形式に出力できますが、PDFは見栄えが綺麗で、単純な指定で、
結構それっぽく?仕上がるので、便利です。基本文字切れしないし。

そんなPDFの小技の一部です。

data LB;
subjid='A';visit='サイクル1';val=100;output;
subjid='A';visit='サイクル2';val=100;output;
label SUBJID='症例番号' VISIT='サイクル' VAL='検査値';
run;

data VITAL;
subjid='B';visit='サイクル1';val=50;output;
subjid='B';visit='サイクル2';val=70;output;
label SUBJID='症例番号' VISIT='サイクル' VAL='検査値';
run;

適当なデータがあって

ods pdf file="display1.pdf";
 proc print data=lb;
  by visit;
 run;
 proc print data=vital:
  by visit;
 run;
ods pdf close;

こんな感じで実行すると












こんな感じですね。

今回注目なのは
左側にある「しおり」の部分です。

「Printプロシジャ」―「サイクル=サイクル1」-「データセット WORK.LB」とかって
勝手になってます。

SAS知っている人に見せるなら、解ってもらえるのですが、以前まったく知らない人に
出力結果を速報として(親切で)あげようと思ってods pdfでぱっと作って差しあげた際
その人から「Printプロシジャ」ってなに?WORK.ってなんなの?とか聞かれて
1つ1つ説明した挙句、「わかんないから手で普通の言葉に直して、あと最終レポートも早く作ってね」と言われて、まあ、そりゃそうかと思いつつ、ポチポチ手で直した寂しい記憶があります。


でもそういう時

ods pdf file="display2.pdf";
 ods proclabel='臨床検査';
 proc print data=lb
  contents="データ元:LB";
  by visit;
  pageby visit;
 run;

 ods proclabel='バイタルサイン';
 proc print data=vital
  contents="データ元:VITAL";
  by visit;
  pageby visit;
 run;
ods pdf close;


こんな感じで、色々工夫できます。

先に実行結果から


ods proclabelでプロシジャ出力の最上位のしおりを指定できます。
byはby変数がそのまましおりになりますが、pageby等で、ページを分けることができます。
contents=で、元データのしおりを制御できます。

実は、もっと山ほどオプションがあって、階層いじったりもできるのですが、とりあえずここまで。










ユーザー定義フォーマットの確認やオプションの確認など

自分用のメモです。

オプションとユーザー定義フォーマットを確認したい時にもう100回くらい、書き方忘れるのでここに書きます。

proc options define;
run;

で使用可能なオプションの説明がログに山ほどでる。

proc options option=firstobs define;
run;

とoption=オプション名で指定すればそのオプションだけ調べれる。

けど大体、ヘルプかリファレンスみるかwebで調べる方が詳しくわかる。


ユーザー定義フォーマットの中身を確認するfmtlibオプションを、いつも忘れるので。


proc format;
 value SEX 1='男'
           2='女';
run;

proc format lib=work fmtlib;  
run;









データセットに吐き出す場合は

proc format lib=work cntlout=A1;  
run;


データセットから呼び込む場合はcntlinで。


ods graphicsで作成される複合グラフを1つ1つのプロットに分解する話

データは適当です。

data Q1;
X=1;Y=4;output;
X=2;Y=5;output;
X=5;Y=8;output;
X=6;Y=9;output;
X=9;Y=12;output;
X=11;Y=10;output;
X=22;Y=26;output;
X=12;Y=15;output;
run;

ods graphicsが有効になっている状態で統計プロシジャをまわすと

ods graphics on;
proc reg data=Q1;
model Y = X;
run;
quit;
ods graphics off;























まあ、いっぱいプロットがでてきますよね。

試しに一つ開いてみると






















こういう複合プロットってありますよね。
凄い見栄え綺麗なんですが、複合状態じゃなく、個々に独立したプロットとして出したい時が
あるとします。

その場合


















だしたい複合プロットの名前を見てから

ods graphics on;
proc reg data=Q1 plots(only)=DiagnosticsPanel(unpack);
model Y = X;
run;
quit;
ods graphics off;

こんな感じで、(unpack)とつけてやります。そうすると























プロットが分解されます。


ここからはおまけですが、

例えば、ODS graphicsで作成される自動プロットも、内部的にはGTLで処理
されているわけなので、コードで再現可能なわけです。

例えば




















さっき、分解したプロットのうちの一つですが、これってどんなコードで作られているんだろうかと
思ったら

また














プロパティみるのですが、今度は「テンプレート」って部分をみます

















あとはテンプレートの表示タブから












階層をたどり












































目当てのテンプレートを発見したらダブルクリックすれば



こんな感じで、さっきのグラフを作っているGTLを入手できます。

ちなみに僕は45度線の書き方がわからない時に、この方法でゲットしました。