2016-08-25 8 views
0

私はSASで作業しており、DOループ内にいくつかのマクロ変数を作成する必要があります。これは私のコードの一部です:SASで&&マクロ変数を使用する方法

%if &dsempty888=0 %then %do; 
    data _null_; 
    set freq_&&var&i; 
     if &&var&i=888888888 then do; 
      call symput("cont8_&&var&i",percent); 
     end; 
    run; 
%end; 
%if &dsempty888=1 %then %do; 
    %let cont8_&&var&i=0; 
%end; 

%if &dsempty999=0 %then %do; 
    data _null_; 
    set freq_&&var&i; 
     if &&var&i=999999999 then do; 
      call symput("cont9_&&var&i",percent); 
     end; 
    run; 
%end; 
%if &dsempty999=1 %then %do; 
    %let cont9_&&var&i=0; 
%end; 


%if &dsempty444=0 %then %do; 
    data _null_; 
    set freq_&&var&i; 
     if &&var&i=444444444 then do; 
      call symput("cont4_&&var&i",percent); 
     end; 
    run; 
%end; 
%if &dsempty444=1 %then %do; 
    %let cont4_&&var&i=0; 
%end; 

このコードはi=1 to &endから実行する別のDOループ内です。 このマクロの変数cont4_&&var&icont8_&&var&icont9_&&var&iは、コストがかかりすぎて...ループの外側で使用できなくなります。私はそれらを例えば&&cont4_&&var&iと名付けようとしました。しかし、明らかにSASはマクロを解決しません。 実際にはループの内部でマクロが作成されますが、私が外に必要なときに呼び出す方法はわかりません。

どうすれば修正できますか?

ありがとうございます。

+0

また、[この質問](http://stackoverflow.com/questions/24895197/resolving-multiple-ampersands-を参照してくださいwith-macro-variables)と[複数質問](http://stackoverflow.com/questions/22903856/sas-macro-ampersand/22915555#22915555)を参照してください。 – Joe

答えて

4

ここでは多くの問題が発生しているので、ここでは簡単にしましょう。ここでは非常に簡単な例です。これは、例えば、何かを行います。

%let var1 = age; 
%let var2 = height; 
%let var3 = weight; 

proc freq data=sashelp.class noprint; 
    tables age/out=freq_age; 
    tables height/out=freq_height; 
    tables weight/out=freq_weight; 
run; 


%macro get_freqs(var_count=); 
    %do i = 1 %to &var_count.; 
     data _null_; 
     set freq_&&var&i; 
     call symput("cont4_&&var&i",percent); 
     run; 
    %end; 
%mend get_freqs; 

%get_Freqs(var_count=3) 

しかし、今、私たちはもちろん

%put cont4_&&var&i; 

をすれば&iは意味がありませんので、それは、動作しません。その代わりに、たとえば1と置き換えます。

%put cont4_&&var1; 

ここでは何かを取得します。しかし、私たちは有用なものは何も得ていません。変数名だけです。しかし、少なくともそれは何かです!

ここでは、実際には2番目の&は必要ありません。

%put cont4_&var1; 

しかし、我々は、マクロ変数を使用する前に、この&が必要になります。

%put &cont4_&var1; 

をしかし、今、我々は警告メッセージ、CONT4_ not resolvedを取得します。さて、&var1が解決されるまで、&を追加してマクロ変数の解像度を遅らせてみましょう。

%put &cont4_&var1; 

これは助けられ、今はCONT4_AGE not resolvedと言います。何故なの?それを定義するのに、call symputを使用しました。

問題はスコープです。 call symputはおそらくそれを局所的にスコープしました。つまり、マクロ内で定義されていて、マクロの外側では定義されていませんでした。このためにはcall symputxを使用し、グローバルスコープを与えます。

%macro get_freqs(var_count=); 
    %do i = 1 %to &var_count.; 
     data _null_; 
     set freq_&&var&i; 
     call symputx("cont4_&&var&i",percent,'g'); 
     run; 
    %end; 
%mend get_freqs; 

これは、&cont4_ageをマクロの外側で定義したいとSASに伝えます。それ以外の場合は、マクロ内でのみローカルで利用可能になり、クリーンアップされます。

%put &&cont4_&var1; 

をしかし、あなたは再び&iを反復処理したい場合、それは少しより複雑です:

は今、これは動作します。これらのアンパサンドを複数回遅延させ、いくつかのパスを許可する必要があるからです。ここで

は、どのような作品だ:

%macro iterate_i(var_count=); 
    %do i = 1 %to &var_count.; 
    %put &&&&cont4_&&var&i.; 
    %end; 
%mend iterate_i; 

%iterate_i(var_count=3); 

はなぜ &のが必要なのでしょうか?さて、&&cont4_&var1になる必要がありますか?それは最初のパスで起こります。ここでは3つのパスは以下のとおりです。

&&&&cont4_&&var&i - >&&cont4_&var1 - >&cont4_age - > 5.26 ...

各パスは、次の処理が行われます。

  • &&

    - >&(と次の通過のために保存)
  • & - >マクロ変数を解決

だから、それはそれらを反復する方法です。もちろん、明示的に任意のレベルのマクロ変数で指定することができます - これらの作業のため、すべての:

%let i=1; 
%put &&&&cont4_&&var&i; 
%put &&cont4_&var1; 
%put &cont4_age; 
関連する問題