2019年5月1日水曜日

luaでcall executeっぽいことを実行する話

call executeはご存知の方も多いと思います.データセットの変数を使ってプログラムを繰り替えすやつですね.もちろん便利は便利なんですが,セミコロンを間違ったりなんだりと書き方がややこしいと個人的に思います.
 データセットの変数を読み込んで繰り返しプログラムを実行するのを,executeではなくluaで書くこともできることの紹介です.


例えばa,b,cの三つのデータセットに対してcontentsプロシジャを実行するプログラムをexecuteで書くと以下の通りです.正直このくらいのプログラムなら複雑なこともないのですが...

* --- 読み込み元 ;
data _IN ;

  _dt = "A" ; output ;
  _dt = "B" ; output ;
  _dt = "C" ; output ;

run ;

*----- execute 実行;

data _null_ ;
    set _IN ;
   
    call execute("proc contents data=" || _DT || " varnum short ;") ;
    call execute("run ;") ;
   
run ;

ここからが同じ内容をluaで書いたプログラムです.executeでは読み込む変数を持ったデータセットをsetしていますが,luaだとopenしてget_valueします.実際に実行したいプログラムを””で挟まないので,マクロ変数を使うときにクオートを気にしなくていいのがストレスが少ないです.実に毛根に優しい.
ただし実行ログにsas.submitで展開されるプログラムが表示されるのですが,その時にマクロ変数は展開されないままっぽいです.実に惜しい.@@で挟んだluaのローカル変数は展開されてくれるんですがね...

*---- lua実行 ;

%let _opt = short ;

proc lua ;
submit ;

local code = [[
  proc contents data = @target@ varnum &_opt. ;
  run ;
]]

local _inid = sas.open("_IN")

while sas.next(_inid) do
  sas.submit(code, {target = sas.get_value(_inid , "_dt") })
end

sas.close(_inid)

endsubmit ;
quit ;

lua実行ログの一部が以下の通りです.読み込むデータのBとCはろぐに出ますが,オプションのshortは展開されずにマクロ変数の名前が表示されています.
実行するとちゃんとshortオプション効いてるので ,luaとしてはマクロ変数を展開せずに実行時に展開しているんでしょうね.

proc contents data = B varnum &_opt. ;
run ;
NOTE: PROCEDURE CONTENTS処理(合計処理時間):
処理時間 0.00 秒
CPU時間 0.01 秒
proc contents data = C varnum &_opt. ;
run ;
NOTE: PROCEDURE CONTENTS処理(合計処理時間):
処理時間 0.00 秒
CPU時間 0.01 秒

0 件のコメント:

コメントを投稿