散布図行列 というか複合パネルのグラフ

 SASユーザー総会2023で「SASによる散布図行列の実装」っていう素晴らしい発表があって
https://sas-user2023.ywstat.jp/download.html?n=36&key=ensdaeeadcsr

それが呼び水となって
SASブログの方で
「SASで散布図行列を作図する -layout latticeの仕様について-」
https://superman-jp.hatenablog.com/entry/SAS-GTL-scatterplotmatrix



「新しい散布図行列の作成法Ⅰ」
https://sasonediver.blog.fc2.com/blog-entry-531.html

があがって,なんなの,今はプロットマトリクス作るのがブームなの笑
ってことで,ちょっと,ついでにオマケ情報で 違う作り方を
SAS Oneブログさんの方の「新しい散布図行列の作成法Ⅰ」とおんなじで,とりまSGで作ってそれを貼り合わせてもいいんじゃない?って時に Python呼び込んでも全然ありと思うのですが,私はRWIが楽と思ってます
ほんと楽で…

もうプロットの部分は皆さんがやってるので,特に言いたいことはないので,合成法だけ
















👆これをつかって3*3のプロットマトリクスにしてみますね

options printerpath=png nodate nonumber  papersize=('15cm' ,'15cm')  ;

ods printer file='XXX\TEST.png' nogtitle dpi=500;

title;

data _NULL_;

dcl odsout ob();

  ob.layout_gridded( columns:3, rows:3 );

  ob.region();

  ob.image( file: "XXX\PharmaSUG.png" );

  ob.region();

  ob.image( file: "XXX\PharmaSUG.png" );

  ob.region();

  ob.image( file: "XXX\PharmaSUG.png" );

  ob.region();

  ob.image( file: "XXX\PharmaSUG.png" );

  ob.region();

  ob.image( file: "XXX\PharmaSUG.png" );

  ob.region();

  ob.image( file: "XXX\PharmaSUG.png" );

  ob.region();

  ob.image( file: "XXX\PharmaSUG.png" );

  ob.region();

  ob.image( file: "XXX\PharmaSUG.png" );

  ob.region();

  ob.image( file: "XXX\PharmaSUG.png" );

run;

ods printer close;




















ob.layout_gridded( columns:3, rows:3 ); 
👆ここでマトリクス構造を指定したら
あとは

  ob.region();

  ob.image( file: "XXX\PharmaSUG.png" );

で順番に画像ファイルを指定するだけ

チョー簡単

Dataset-JSONとかの話②

読み込みとかだと こんな感じか? まだまだ これから検証してかないとですが 


%macro imp_json(inpath=XXXX,ds=);

filename js "&inpath\&ds..json" encoding="utf-8";

libname in json fileref=js ;

proc copy in = in out = work ;

run ;

libname in clear ;

filename js clear;


data _null_;

set Itemgroupdata_ig_&ds.;

call symputx("name",name);

call symputx("label",label);

run;

 


data _null_;

set Ig_&ds._items end=eof;

 call symputx( cats("rename",ordinal_items), cats("element",ordinal_items)||"="|| name );

 call symputx( cats("label",ordinal_items), cats("element",ordinal_items)||"='"|| cats(label,"'") );


 if ^missing(displayFormat) then do;

  call symputx( cats("format",ordinal_items), cats("element",ordinal_items)||" "|| cats(displayFormat,"") );

 end;

 else do;

  call symputx( cats("format",ordinal_items),"");

 end;


 if eof then call symputx("last_ordinal_items",ordinal_items);

run;

options mprint;


%macro create;

data &name(label="&label" drop=ordinal_IG_&ds ordinal_itemData ITEMGROUPDATASEQ);

 set Ig_&ds._itemdata;

 rename

 %do i = 1 %to &last_ordinal_items;

  &&rename&i

 %end;

 ;

  label

 %do i = 1 %to &last_ordinal_items;

  &&label&i

 %end;

 ;

 format

 %do i = 1 %to &last_ordinal_items;

  &&format&i

 %end;

 ;



 ;

 run;

 %mend create;


 %create;


%mend imp_json; 


Dataset-JSONとかの話

医薬業界で,主に臨床試験データの標準形式のCDISCに絡んだ話. xptに代わる次世代のデータフォーマットとして提案されてる中にJSON形式のファイルもあって Dataset-JSONとかって提案されてます
https://www.cdisc.org/dataset-json
👆これのspecificationのところで 例示がされてます

例えばSASでどう作るかって話で,

見る感じ,定義情報をいろいろ持たせるので,そこはdefineから持ってくるなり,他の与え方をするなりがいるんですが,それ以前に SASでJSONファイルって作れるのって人が多いと思うので,そこだけ

data DM (label="Demographics");

attrib

STUDYID label="Study Identifier " length= $5000.

DOMAIN label="Domain Abbreviation " length= $200.

USUBJID label="Unique Subject Identifier " length= $200.

AGE label="Age " length= 8.

;

STUDYID="MyStudy";USUBJID="001";DOMAIN="DM";AGE=56;output;

STUDYID="MyStudy";USUBJID="002";DOMAIN="DM";AGE=26;output;

run;


data DM_1;

attrib ITEMGROUPDATASEQ label="Record identifier" length=8.;

 set DM;

 ITEMGROUPDATASEQ=_N_;

 run;

 proc sort data=DM_1;

  by STUDYID USUBJID;

run;

ods noresults;

ods output Position=Position;

ods output Sortedby=Sortedby;

proc contents data=DM_1 varnum ;

run;


data dataset_item;

length OID name label type displayFormat $200.;

set Position;

call missing(of displayFormat);

if Variable = "ITEMGROUPDATASEQ" then OID=Variable;

else OID = cats("IT.",Variable);

name=Variable;

if ^missing(displayFormat) then do;

displayFormat=format;

end;

if Type in ("数値") then type="integer";

else type="string";

keep OID name label type displayFormat;

run;


ここまでは適当な下準備なので,いいとして.
今回いいたいのは Proc JSONをつかって
writeステートメントで構造や値を直に作成でき
exportで任意のデータセットの内容を変換してJSONファイルの中に含めれるよって点.
以下は,とりあえず試してみただけで,精査してないのと items作る部分は,本来データセットの情報を取り出してつくるのではなく,定義情報から付与すべきのように思うのでそのまま使ったりしないでくださいね.あくまでproc JSONを紹介したいだけなので

proc json out = "XXXXX\dm.json" pretty;

 write open object ;


   write values "creationDateTime"  "2023-03-22T11:53:27";

   write values  "datasetJSONVersion"  "1.0.0";

   write values  "fileOID"  "www.sponsor.org.project123.final";

   write values  "asOfDateTime"  "2023-02-15T10:23:15";

   write values  "originator"  "Sponsor SASYAMA";

   write values  "sourceSystem"  "SAS 9.4";

   write values  "sourceSystemVersion"  "M7";



write values "clinicalData";

write open object;


  write values "studyOID"  "xxx";

  write values  "metaDataVersionOID"  "xxx";

  write values  "metaDataRef"  "https://metadata.location.org/api.link";


  write values "itemGroupData";

  write open object;


write values "IG.DM";

     write open object;

write values "records" 2 ;

write values "name" "DM" ;

write values "label" "Demographics" ;


write values "items" ;/* attribute array */

write open array;

     export dataset_item /   nosastags;

  write close;


write values "itemData" ;/* record array */

write open array;

      export DM_1 / nokeys  nosastags;

  write close;

write close;


  write close;

  write close;

 write close;

run ;






SASユーザー総会2023









 https://sas-user2023.ywstat.jp/


基本,ただの宣伝みたいな記事は出さないのがポリシーなのですが
ちょっと今回はお許しを.

今年もSASユーザー総会開催します.

そして光栄なことに 私は世話人にしていただきまして 運営にも携わらせていただきます.
何卒宜しくお願い致します


セルオートマトン:1次元:Rule 30の話

セルオートマトンという研究分野があります.n次元内でのセルという単位を設定します.セルには事前に何種類かの値(状態)を設定します.時点t においてのセルの状態と隣接(近傍)のセル状態によって、何らかの状態遷移式を通して,次時点(t+1)の各セルの状態が決定されると設定しちゃいます.

1次元セルオートマトンの場合,セルの展開は直線であり,1次元配列xにすると
要素数 i の場合 近傍セルはx{i-1}と x{i+1}になるので

tにおける,x{i-1}とx{i}とx{i+1}の状態によってt+1のx{i}の状態が決定するということになります.

状態を0と1の2つと設定した場合,x{i-1}とx{i}とx{i+1}がとりうるのは

左   中     右

0 0 0

0 0 1

0 1 0

0 1 1

1 0 0

1 0 1

1 1 0

1 1 1


に8パターンになります

その8パターンにおいて,真ん中のセルx{i}が0と1どちらをとりうるかを考えると
2の8乗になるので256通りあることになります
それらは ウルフラム・コードRule0からRule255と呼ばれ,既に研究しつくされています

まずは一番有名なRule 30 について

x{i-1} x{i} x{i+1}     t+1のx{i}
0 0 0 ➡ 0

0 0 1 ➡ 1

0 1 0 ➡ 1

0 1 1 ➡ 1

1 0 0 ➡ 1

1 0 1 ➡ 0

1 1 0 ➡ 0

1 1 1 ➡ 0


x{i}の次時点の値01111000を2進数から10進数に直すと30なのでRule30と呼ばれています

Rule30でいくと 仮に初期状態が





なら次の状態は(両終端のその先は0とします)







こうなります,例えばtで左から2番目のセルがt+1で1になっているのは
0 0 1➡ 1の遷移ルールに従うからです 
さて,このようにしてtをドンドンすすめていって,値がどう遷移していくかを
仮に,蓄積してビジュアライゼーションすると何が起こるかを見てみましょう

今,配列数を200要素として,次時点の値を格納する配列も同数用意し
Rule 30をそのまま select文にぶち込んでしまって,tをオブザベーション数と考えて
100回ほどループさせてみます

data wk1;
array col{200}  (200*0);
array ncol{200}  (200*0);

col{100}=1;

do obs = 1 to 100;
do i = 1 to 200;
if obs = 1 then do;
ncol{i}=col{i} ;
end;
else do;
if i=1 then pattern=cats(0, col{i},col{i+1});
if (1+1)<=i<=(200-1) then  pattern=cats(col{i-1},col{i},col{i+1});
if i=200 then pattern=cats(col{i-1}, col{i},0);
/*rule*/
select(pattern);
  when("000") ncol{i} =0;
  when("001") ncol{i} =1;
  when("010") ncol{i} =1;
  when("011") ncol{i} =1;
  when("100") ncol{i} =1;
  when("101") ncol{i} =0;
  when("110") ncol{i} =0;
  when("111") ncol{i} =0;
end;
end;
end;
  output;
  do i = 1 to 200;
    col{i}=ncol{i} ;
  end;
end;

keep ncol:;
run;

結果にういて,0を白色,1を黒色として,SAS RWI(Report Writing Interface)で描画してみます(先のコードと同じステップでもいいですが,見やすさのためデータステップを分けました)

data _null_;
set wk1 end=eof;
array AR ncol:;
if _N_=1 then do;
  dcl odsout ob();
ob.table_start();
end;
ob.row_start();
do over AR;
if AR=1 then do; background="black";color="black";end;
else if  AR=0 then do; background="white";color="white";end;
text=catx(" "," color=",color," height=0.01 width=0.01  vjust=center background=",background);
ob.format_cell(data:AR,style_attr:text);
call missing(of background color);
end;
ob.row_end();
if eof then do;
ob.table_end();
end;
run;














↑がSASの出力ですが,このパターンはイモガイの一種の紋様と類似します.
これは貝殻に格子状に存在する色素細胞が隣接細胞に活性阻害の影響を与えるため,天然のセルオートマトンとして働いているからという原理のようです














画像と,紋様とRule30については以下より参照
(Coombs, Stephen (February 15, 2009), The Geometry and Pigmentation of Seashells
https://www.maths.nottingham.ac.uk/plp/pmzsc/pdfs/Seashells09.pdf


こんな風に,セルの相互関係と単位時間での状態遷移を考えたセルオートマトン,原理はシンプルでプログラムでの実装も(1次元なら特に)平易ですが,
Rule 30は面白いことに,ある生物学的過程を綺麗にシミュレートできました

次もこの面白いセルオートマトンのことをもっと紹介していこうかなと思います~