0

ダッシュとピリオドを含むことができる文字列と、ダッシュとピリオドがアンダースコアに置き換えられた同じ文字列のクリーンアップされたバージョンの 2 つのパラメータを必要とするマクロがあります。

以下の作品:

%let foo = abc.def;

%mymacro(firstpar = &foo, secondpar=%sysfunc(translate(&foo,"__","-.")));

%let foo = abc-def;

%mymacro(firstpar = &foo, secondpar=%sysfunc(translate(&foo,"__","-.")));

...しかし、そのような変数の長いリストをループするにはどうすればよいでしょうか? リストの要素を一度に 1 つずつプレースホルダー変数に割り当ててからコマンドを評価するか、コマンド文字列に直接代入する (ただし、明示的に要求するまで評価しない) ための標準的なイディオムはありますか?

%DO_WHILEマクロ ライブラリを使用してみましたが、 &foos に句読点が含まれていない限りうまく機能します。もしそうなら、それは失敗し、私が試した引用の組み合わせはそれを機能させることができません.

私の実際のマクロは長すぎて複雑で、ここに投稿するには実用的ではありません。願わくば、この一般的な質問が答えられるほど明確であることを願っています。

%mymacro(firstpar = &foo, secondpar=%sysfunc(translate(&foo,"__","-.")));「1回限りの呼び出しのように見え、値のリストが大きいマクロを繰り返し呼び出すための推奨される戦略は何fooですか?」

または、別の言い方をすれば、「SAS で Rparse()deparse()機能に最も近いものは何ですか?」

4

3 に答える 3

2

私はそれらに精通していないので、Rの構文解析と逆解析に関係することはできません。ただし、最初のパラメーターを渡して、マクロ内に2番目のマクロ変数を作成します。以下を参照してください。FIRSTPARはサンプルに含まれているとおりです。置換する必要のある文字を含むTRANSLATEパラメーターを含めます(デフォルトは「。」)。

%macro mymacro(firstpar=,translate=.);

  data _null_;
    firstpar="&firstpar";
    translate="&translate";
    secondpar="&firstpar";
    subi=1;
    do while(length(translate)>=subi);
      secondpar=tranwrd(secondpar,substr(translate,subi,1),"_");
      subi+1;
    end;
    call symput('secondpar',secondpar);
  run;
  %put &secondpar;
%mend mymacro;

ピリオドとダッシュを置き換えます。

%mymacro(firstpar=abc-de-fg.hi-.k,translate=.-)

ピリオド、ダッシュ、コンマを置き換えます。

%mymacro(firstpar=%str(abc-de,fg.hi,.k),translate=%str(.-,))

これらの2つの例は、SECONDPARマクロ変数を次のようにログに出力します。

abc_de_fg_hi__k
于 2012-12-03T09:24:02.000 に答える
0

ここで「リスト」について言及したため、このリストをマクロに解析する方法によってアプローチが異なります。リストがマクロ変数として直接使用できる形式になっている場合、たとえば次のようになります。

%let foo = abc-def abc-d-af abd-c-dgf; 

ここでは、個々のパラメータはスペースで区切られています。マクロ変数はすべてを保持します。次に、パラメーターを 1 つずつ抽出できます。

 %macro mymacro(firstpar = &foo, secondpar=%sysfunc(translate(&foo,"__","-.")));
   %do i = 1 %to %sysfunc(countw(&foo,' '));
          %let p1 = %scan(&foo, &i, ' ');
          %let p2 = %scan(&secondpar, &i, ' ');
          *<original macro statements>*
   %end;

COUNTWパラメータの数を取得し、これらのパラメータを取得するために使用しSCANます。

リストを最初にインポートする必要がある場合。追加の手順があります:

 data tmp;
 input foo $;
 datalines;
 abc-def
 abcd-def
 abc-d-af
 ;
 run;

 proc sql noprint;
   select foo into :foo separated by ' ' from tmp;
 quit;

これで、リストが に保存されfoo、スペースで区切られました。次に、上記のマクロに解析できます。

于 2012-12-03T10:49:07.573 に答える
0

簡単な質問は、既存のデータからマクロを繰り返し呼び出す方法だと思います。多くの場合、そうではありません。多くの場合、通常の SAS コードでは何でも単純に実行します。しかし、あなたは私たちに何の情報も提供してくれなかったので、マクロを繰り返し呼び出す正当な理由があるのか​​もしれません (通常は避けようとしますが、私は確かにそうすることがあります)。

上記の DavB の回答をこの回答に組み込みます。両方の値をパラメーターとして持たず、最初のパラメーターのみを使用してから、マクロ内でそれを 2 番目のパラメーターに変換します。

データ ドリブン マクロ呼び出しを作成するには、約 10 通りの方法があります。ここに3つあります。

%macro foo(param=);
%let second_param=%sysfunc(translate(&param,"___","-.a"));
%put &param &second_param;
%mend foo;


*Method 1: Call Execute.  This puts code in a queue to execute after the data step completes.  
    This has some advantages, namely that you can build code easily and can modify it with data step functions, 
    and some disadvantages, namely that some timing issues (when things happen internal to SAS) exist 
    and can be difficult to remember/work around.  Not used all that often as a result of those timing issues 
    but for simple things can be useful.;
data _null_;
set sashelp.class;
mcall = cats('%foo(param=',name,')');
call execute(mcall);
run;

*Method 2: PROC SQL select into.  This creates a list and stores it in a macro variable.  
    Quick and easy (much shorter code-wise) compared to the other solutions, but has one significant limitation:
    a hard limit to how many total characters can be stored in a macro variable (I forget exactly how much, but around 20,000).
    So if you are calling the macro a thousand or more times this might fail - it writes a warning to the log if so.
    Use NOPRINT with PROC SQL unless you want to see what is generated.;
proc sql;
select cats('%foo(param=',name,')') into :mcalllist separated by ' ' from sashelp.class;
quit;
&mcalllist;

*Method 3: Include file generation.  This creates an actual text file with your code in it, then you include that code.
    In some ways the most transparent - you can easily debug the code - but also a lot of lines of code to write comparatively.
    Does not have the length limitation of the PROC SQL method, although it does have the normal limitations of included code.
    The temp file is written to your WORK directory, so you can navigate to that to see the contents, and/or use a non-TEMP file
    and write it out to a directory of your choosing in order to see it.
;

filename foo temp;
data _null_;
file foo;
set sashelp.class;
mcall = cats('%foo(param=',name,')');
put mcall $;
run;
%include foo;
于 2012-12-03T21:10:33.927 に答える