7

SAS 9.3 マクロ言語のfor inループ( Pythonや R など) に相当するものをしばらく探しています。DO ループは解決策のようですが、私が望むとおりには機能しませんでした。DO ループを使用してデータ ステップでそれを行う方法を確立しましたが、マクロ言語では機能しません。たとえば、データ ステップでは、次のコードが機能しています。

DATA _NULL_;
  DO i = 1,3,5,9;
    PUT i;
  END;
RUN;

そして、期待どおりのログプロンプト:

1
3
5
9

マクロの%DOループで同じことをしようとすると、エラーが発生します。

%MACRO test();
  %DO i = 1,2,4,9 ;
    %PUT i = &i;
  %END;
%MEND;

%test();

ログには次のメッセージが表示されます。

ERROR: Expected %TO not found in %DO statement.
ERROR: A dummy macro will be compiled

私は SAS と stackoverflow にまったく慣れていないので、私の質問があまりにもばかげていないことを願っています。Python と R でこれを行うのは非常に簡単ですが、SAS で行うには簡単な方法が必要です。

助けてくれてありがとう - J. Muller

4

2 に答える 2

6

SAS マクロ言語でこのパターンに最も近いものは次のとおりです。

%MACRO test();

%let j=1;
%let vals=1 2 4 9;
%do %while(%scan(&vals,&j) ne );
  %let i=%scan(&vals, &j);

  %put &i;

  %let j=%eval(&j+1);
%end;
%MEND;

%test();

(警告:これをテストできるSASインストールがもうないため、テストされていません。)

于 2013-03-22T14:47:56.730 に答える
4

あなたは確かにこの方法でそれを回避することができます:

options mindelimiter=,;
options minoperator;
%MACRO test();
  %DO i = 1 %to 9 ;
    %if &i in (1,2,4,9) %then %do;
    %PUT i = &i;
  %END;
  %end;
%MEND;

%test();

ただし、マクロ内のループを制御しようとするのではなく、マクロを複数回実行することで、通常、この種の呼び出しを回避できると思います。たとえば、データセットとマクロを想像してください。

data have;
input x;
datalines;
1
2
4
9
;;;;
run;

%macro test(x);
%put &x;
%mend test;

次に、そのリストの値ごとに %test() を 1 回呼び出します。わかりました、簡単にできます。

proc sql;
select cats('%test(',x,')') into :testcall separated by ' ' from have;
quit;

&testcall;

これは、ループ内の %do と同じように機能しますが、データ駆動型であることを除けば、呼び出しを変更したい場合は、データセットを変更するだけです (または、データが変更された場合、呼び出しは自動的に変更されます!)。一般に、SAS は、完全に記述されたコードとしてではなく、データ駆動型プログラミングとして設計された方が効果的です。

于 2013-03-22T14:46:39.150 に答える