任意の変数の後に変数を追加する

[OS] ALL
[リリース] ALL
[キーワード] Base, add, variable, position

[質問]

既存のデータセットに新しく変数を追加するとき、変数の位置が最後になります。
これを任意の位置(たとえば、任意の変数の後)に追加するにはどのようにすればいいでしょうか。

[回答]

変数の位置は、DATAステップでの出現順になります。位置を直接指定する機能はありません。
ただし、ダミーのFORMATステートメントや、LENGTHステートメントを使って変数のリストを記述することで、位置を変更できます。

下記の例では、変数がA1, A2, B1, B2のように並んでいるとき、A2の後ろにA3を追加するダミーのFORMATステートメントで、追加する位置より前の変数と追加する変数を指定しています。


  DATA sample;                 /* サンプルデータセット作成 */
    INPUT a1 a2 b1 b2 x $ y $ z $;
  CARDS;
  1 2 3 4 A B C
  5 6 7 8 X Y Z
  ;
  RUN;

  DATA sample;
    FORMAT a1 a2 a3;      /* ダミーのFORMATステートメント */
    SET sample; 
    a3=a1*100;
  RUN;

変数が多い場合は、マクロを使用して、ダミーのFORMATステートメントの記述を簡略化できます。
次の例を参照してください。


  %MACRO add_var1(indata,var);
    %* indata: データセット名を指定 ;
    %* var: どの変数の後に追加するか、変数名を指定 ;
    %GLOBAL n_var;

    PROC CONTENTS DATA=&indata
      OUT=_work1(KEEP=name varnum) NOPRINT;
    RUN;
    PROC SORT DATA=_work1;
      BY varnum;
    RUN;
    PROC SQL NOPRINT;
      SELECT varnum INTO :n_var FROM _work1
             WHERE UPCASE(name) = "%UPCASE(&var)";
    QUIT;

    %DO i=1 %TO &n_var;
      %GLOBAL name&i;
    %END;
    DATA _NULL_;
      RETAIN flg 0;
      SET _work1;
      IF flg=1 THEN STOP;
      IF varnum = &n_var THEN DO;
        flg=1;
      END;
      CALL SYMPUT('name' || LEFT(_n_),name);
    RUN;
  %MEND add_var1;

  %MACRO add_var2(add_var);
    %* add_var: 追加する変数名を指定 ;
    FORMAT
      %DO i=1 %TO &n_var;
        &&name&i
      %END;
      &add_var;
  %MEND add_var2;

                                /* マクロの実行例 */
           /* NEWという変数をB2の後に追加する場合 */

  %add_var1(sample,b2);

  DATA sample;
    %add_var2(new);
    SET sample;
    new=b1+b2;
  RUN;