うずまき2017 powered by Jun-Systems

耳管開放症, SAS, 統計解析, 人工知能, プログラミングそれに思考

*

SASで変数リスト内の全変数に順番に同じ処理をかけていくマクロ

   

SASであるデータセットdatとデータセット内の変数がいくつかあったときに,そのデータセット内の指定した複数の変数に順番に同じ処理をかけていくマクロを作りたかったんですよ.ちなみに変数名には何の法則性もない.

DATA dat;
INPUT a1 k4 g31 i23 tt2a;
CARDS;
   1 1 1 1 1
   2 2 2 2 2
   3 3 3 3 3
;
RUN;

まあなんかこんなデータセットがあるとするじゃないですか.
んで,この中のある指定した複数の変数(たとえばa1とg31とtt2a)に対して同じ一連の処理をかけたいわけですよ.データステップとプロシージャをそれぞれごちゃごちゃ走らせるようなね.

執念で書ききったゴミみたいなクソコードを貼ります.

%MACRO doAll(dat,varlist);
   %LET vars = %SYSFUNC(COMPBL(&varlist)); *バグ取り 空白の重複除去;
   %LET n = %SYSFUNC(COUNTC(&vars,' ')); *空白の数をカウント;
   %LET n = %SYSEVALF(&n + 1); *変数の数は空白+1;

   *こっからやりたい処理書いてく的な;
   %DO i = 1 %TO &n; *変数の数だけループ;
      %LET var = %SYSFUNC(SCAN(&varlist,&i,' ')); *i個目の変数をvarに格納;
      PROC MEANS data=&dat NOPRINT;
         var &var;
         OUTPUT out=_max(KEEP=_max) max=_max;
      RUN;
      DATA &dat;
         DROP _max;
         IF _N_ = 1 THEN SET _max;
         SET &dat;
         &var = &var / _max;
      RUN;
   %END;
%MEND;
%doAll(dat=temp,varlist=a1 g31 tt2a)

マジで死んだほうがいいようなクソコードですね.簡単に言うと,マクロを走らせる際に引数varlist内に空白で区切った変数名を指定したら,varlist内の変数の数を数えてnに格納しといて,それをDOループで順番にグローバルマクロ変数に叩き込んで変数名を差し替えながら処理を走らせていくって感じです.(今見たらvarlistの最後に空白が入ってた時のバグが取れてない)
応用すると複数のデータセット内の複数の変数に対しても適用できますが,コードのアホ度がより増加します.
今回はデータセット内の指定した全変数をそれぞれの変数の最大値で除すというクソどうでもいいやつなんでわざわざこんなの使わなくても多分できるんですけど,前にもっと面倒なことの実装のプロセスでこれをやろうとしてできなかったんですよね.

ほんとは↓みたいな感じでやれたらいいのになーと思ってるんですけど.グローバルな感じで配列とか組めたらなーみたいな.

%MACRO doAll(dat,varlist);
   array vars(*) &varlist;
   %DO i = 1 %TO dim(vars);
     PROC *** data=&dat;
        var vars{&i}
     RUN;
   %END;
%MEND;
%doAll(dat=temp,varlist=aa bb dd)

DATA _NULL_でCALL SYMPUT使って無理やり実装するのとどっちがラクか考えてこうなりました.

カスみたいなクソコードだし絶対もっとスマートな方法があると思うんで,「あーこういう変なことやる奴もいるんだな」みたいな感じで見てくれればいいです.


 - SAS, SAS Programming , ,

Message

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

  関連記事

no image
SASで直接twitterを検索してTLをインポート(PROC HTTP/Twitter OAuth)
no image
SASのPROC SQLで一括操作(変数名の変更 / ダミー変数操作など)
no image
SASでHHI(ハフィンダール指数)を計算するマクロを作った
実用性重視のSASコマンド集
no image
データ分析の重要性とオープンデータ活用の潮流
no image
SASで横方向の合計を出すには PROC SQL part2
no image
SAS上で走っているRとSASでのデータセットの受け渡し
SASでランダムサンプリングしてグループ分けするマクロ
SAS超基礎1 データの読み書き
no image
2014年IT関連まとめ