YAML形式のファイルをSASから出力する

医薬の話,Analysis Results StandardってCDISCの標準の一つにYAMLっていうファイル形式がめっちゃ出てくる.

しかしSASにはProc JSONのようにYAMLファイルを簡単に作ってくれる仕組みがない.構造としてYAMLはJSONの上位互換のようなので,JSONで出してYAMLに変換してもいいけど,まあ普通にSASからダイレクトに作れた方がハッピーでしょうということで,簡単に作ってみた.

要はproc JSONは proc streamにwriteステートメントやexportステートメントといった部品が組み込まれたようなものなので,proc streamに,複数のデータセットをソースとすることができ,その内容を指定構造 として流し込めるパーツマクロがあれば,似たようなものができると考えた

だいたいこういうのやろうって時は,類似のアイデアが過去のPharmaSUGかPhuseかglobal forumにあがってるものだけど,今回は珍しく全くなかった気がする

まだ開発途中で,今はとりあえず,ネスト構造どうやって実装してやろうかなって思ったりしてる

ただ単純なものなら 多分できたっぽいので公開.たぶん現在進行形で似たようなことやらされて困ってる人が業界にいるんじゃないかなぁとか思って一助になれば幸い

とりあえず,任意データセットから,マッピング・シーケンス・マッピングのシーケンスを任意の階層(インデント)で,だせるようにしました.データセットからの絞りもいれたので1obsでマッピングすればスカラーにもなります(スカラーなら手でうてばいいけど,動的にだしたければ可能よってことで)


一応,サンプルでつくったYAMLが正しく認識されて,JSONならこうなるよっていうのは変換サイト(https://codebeautify.org/yaml-to-json-xml-csv)で試して見ました














以下 マクロと 実行サンプル.まだARSの各種公開されてるサンプルほどの構造を全部楽につくれるほどではないけど,ネストの問題さえどうにかすれば,まーSASから 比較的直観的に設計できるんじゃないかなぁとか


/*======================

macroname: ymlexport

author: sasyama

version:0.1 2024-05-27


説明: proc JSONにおけるexportステートメントのノリで使ってください

varlist=に半スペで列記した変数にたいして、index=で指定した階層(1につき半スペ2に変換))さげて出力

cat=で指定できる構造の種類は以下の3つ


[1] mapping

  Name: アルフレッド

  Age: 14


[2] sequence

  - アルフレッド

  - 14


[3] mappingsequence

  - Name: アルフレッド

    Age: 14


さらに構造の下に、マッピングやシーケンスを持った、深い構造の実装については現在検討中


wh=には%nrbquote()を配置

マクロ変数のスコープは未整備。グローバルで、MVAR_i_j MVARNAME_i_j (iはobs分 jは変数分できる) yobs nw__  

----------------------------------

Copyright (c) [2024] [sasyama]

This software is released under the MIT License.

http://opensource.org/licenses/mit-license.php

========================*/

%let nw=__ NEWLINE;

%macro ymlexport(ds=,wh= ,cat=mapping,varlist=,indent=1);

%local yobs;

%let varlist=%sysfunc(compbl(&varlist));

%let varnum = %sysfunc( count( &varlist, %str ( ) ))+1;

%do i = 1 %to &varnum+1;

 %let var&i =  %sysfunc(scan( &varlist,&i, %str ( ) ));

 %put &&var&i;

%end;

%macro dloop;

  %do i =1 %to &varnum;

  call symput(cats("mvarname&i._",_N_),ksubstr(cat(repeat(" ",&indent * 2),vname(&&var&i)),2));

  call symputx(cats("mvar&i._",_N_),&&var&i);

  call symput(cats("mvarseq&i._",_N_),ksubstr(cat(repeat(" ",&indent * 2),"- ",&&var&i),2));

  %if &i=1 %then %do;

call symput(cats("mvarname_mapseq&i._",_N_),ksubstr(cat(repeat(" ",&indent * 2),"- ",vname(&&var&i)),2));

  %end;

  %else %do;

call symput(cats("mvarname_mapseq&i._",_N_),ksubstr(cat(repeat(" ",&indent * 2 + 2),vname(&&var&i)),2));

  %end;

  %end;

%mend;

%let _rc = %sysfunc(dosubl(%str(

data tmp;

 set &ds;

 where &wh;

run;

data _NULL_;

  if 0 then set tmp nobs=NOBS;

  call symputx("yobs", NOBS);

  stop;

run;

data _null_;

 set tmp;

 %dloop;

run;

)));

%do h=1 %to &yobs.;

 %do i = 1 %to &varnum;

   %if %index(%lowcase(&cat),mapping) and %index(%lowcase(&cat),sequence)  %then %do;

&&mvarname_mapseq&i._&h: &&mvar&i._&h &nw.;

  %end;

  %else %if %index(%lowcase(&cat),mapping) %then %do;

&&mvarname&i._&h: &&mvar&i._&h &nw.;

  %end;

  %else %if %index(%lowcase(&cat),sequence) %then %do;

&&mvarseq&i._&h &nw.;

  %end;

 %end;

%end;

%mend;

/*マクロ終わり*/


/*実行例*/

filename sample "フォルダパス\sample.yaml";

proc stream outfile=sample resetdelim="__";

begin

#マッピングの例 &nw.;

sashelp.class: &nw.;

%ymlexport(ds=sashelp.class

             ,wh=%nrbquote(name="アルフレッド")

             ,cat=mapping

             ,varlist=name age sex

             ,indent=1)

--- &nw.;

#シーケンスの例 &nw.;

sashelp.class: &nw.;

%ymlexport(ds=sashelp.class

             ,wh=%nrbquote(name="アルフレッド")

             ,cat=sequence

             ,varlist=name age sex

             ,indent=1)

--- &nw.;

#マッピングをシーケンスにする例 &nw.;

sashelp.class: &nw.;

%ymlexport(ds=sashelp.class

             ,wh=%nrbquote(name in ("アルフレッド","アリス"))

             ,cat=mappingsequence

             ,varlist=name age sex

             ,indent=1)

;;;;

run;


SASユーザー総会2024など

新しいネタを何もやってないのかというと,そういうわけではないのですが,どうにもブログの更新がすぐに滞ってしまいますね..
まさかの2024年初記事.そして宣伝

SASユーザー総会2024








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

昨年,会場キャパシティがギリギリになってしまったので,反省を踏まえて,会場を変えて大きくしました

なので演題大募集中です
幅広い層のユーザーの交流を活性化することを目指しており,チュートリアル的な発表,入門者・初心者向けの演題も大歓迎していますので,できる限り気兼ねなく発表していただければと思ってます.

他の宣伝

大阪SAS勉強会
https://sites.google.com/view/osakasasbenkyokai/%E3%83%9B%E3%83%BC%E3%83%A0
大阪でゆるくやってる勉強会です

Rで実践!美しいTable & Figureを作ろう
https://jea33-preseminar3.netlify.app/
こちらのSAS部分の資料を作らせていただいたり
https://jea33-preseminar3.netlify.app/sas_stata

CDISC 2024 Japan Interchange

https://www.cdisc.org/events/interchange/2024-japan-interchange/program
こっそり発表予定.SASデータセットからDataset-JSONを作る際,読み込む際のメタデータ部分のやりくりはSAS拡張属性使うといいんじゃないですか的な提案

他にもSAS芸人枠でちょいちょい色んなところに顔ださせてもらったり