Proc Luaのsas.write_dsに流す際にvarsテーブルで定義情報を制御してやろうじゃないって話

忘備録の「PROC LUAによる変数作成と行追加のはなし」を読み返してふと思ったこと
(http://sas-boubi.blogspot.jp/2016/09/proc-lua_26.html#comment-form)

既存データセットを上書き更新せずに変数追加はできない。
それはよくわかる。仕様ならしようがない。

代わりにsas.submitでコード流してくれとSAS社からのお達し。
SASデータセットの操作はSASコード実行するのが一番速いので、SAS社の言ってることは正しい。わかる。

けど、それじゃ、Luaで操作してるって感じがないから残念っていうmatsuさんの気持ちも凄いわかる。

じゃあさ、どうせ、setでデータセット読み込んで、データセットを上書き更新しちゃうならsas.load_dsでデータセットをLuaのテーブルにしちゃってさ、
ディスクリプタ部に該当するvars子テーブルの中身をいじって再度write_dsしちゃうのはどう?
処理時間的には非効率だけど、Lua書いてるって感じがして面白いのと、
Lua固有の操作で属性に関与できるから可能性のある考えじゃない?っていう提案。

要するに以下みたいなこと


data Q1;
VAR1=1;VAR2="A";output;
VAR1=2;VAR2="B";output;
run;









proc lua ;
submit;
local TB=sas.load_ds("Q1")
TB.vars.var3={type="C",length=20,label="ラベル"}
sas.write_ds(TB,Q1)
endsubmit;
quit;











write_dsはload_dsで作成される構造と同じテーブルを渡すことで
LuaテーブルからSASデータセットを作ってくれる。

おさらいしておくと、load_dsで作成される構造とは

proc lua;
submit;
local TB=sas.load_ds("Q1")
print(table.tostring(TB))
endsubmit;
quit;

で、自分で確認してほしんですけど(画像でかくなるから)、
テーブル直下に[1]とか[2]とかってobs番号がキーになって子テーブルができて、その中に
各変数名がキーになって値がはいる。
また、それとともにキー[vars]として子テーブルができて,その中に変数名がキーになって子テーブルができて、その中にさらに属性値名がキーになって値が入るわけです。
テーブルの入れ子構造で、本当面白い。

ちなみに、当然の疑問として、varsテーブルを作らずにwrite_dsするとどうなるかという話ですが、以下を実行してみてください。

proc lua ;
submit;
local TB={[1]={X=1,Y="A"}}
sas.write_ds(TB,"Q2")
endsubmit;
quit;

文字値のレングスのデフォが何故か500になったりするから要注意ね。

あと、Luaのテーブルに変換して、またSASデータセットに変換するという迂回をしてるんで速度はsas.submitで捌くのに比べると当然、ゲロ遅くなります。

あと当たり前だけど、ハッシュ型において、絶対的な格納位置みたいな概念ないから
SASデータセットにした際の変数位置って、どうやって制御したもんかなっていうのも課題としてあります。
正直、データハンドリングの本質的には、変数の格納位置なんて本来はどうでもいい。
そこを処理のとっかかりにしたり、やたら縛られるSASが独特なわけで。
本当は、んなもん飾りですよ。偉い人にはそれが、、、。





1 件のコメント: