宏返回一个值

时间:2011-09-13 13:03:40

标签: sas sas-macro

我创建了以下宏。 Proc power返回包含列pw_cout的表Powerdata _null_步骤会将Power的{​​{1}}列中的值分配给宏变量pw_out。我希望宏返回tpw的值,这样在主程序中,我可以在DATA步骤中调用它,如:

tpw

以下是宏的代码:

data test;
   set tmp;
   pw_tmp=ttest_power(meanA=a, stdA=s1, nA=n1, meanB=a2, stdB=s2, nB=n2);
run;

3 个答案:

答案 0 :(得分:11)

@itzy指出为什么你的方法不起作用是正确的。但是 是一个维护你的方法精神的解决方案:你需要创建一个功能计算功能uisng PROC FCMP。事实上,AFAIK,要在PROC FCMP中的函数内调用一个过程,你需要将调用包装在一个宏中,所以你几乎就在那里。

这是你的宏 - 稍加修改(主要用于修复symput语句):

%macro ttest_power;

  proc power; 
     twosamplemeans test=diff_satt 
     groupmeans = &meanA | &meanB 
     groupstddevs = &stdA | &stdB
     groupns = (&nA &nB)
     power = .;    
     ods output Output=pw_out;
  run;

  data _null_;
      set pw_out;
      call symput('tpw', power);
  run;

%mend ttest_power;

现在我们创建一个函数来调用它:

proc fcmp outlib=work.funcs.test;

  function ttest_power_fun(meanA, stdA, nA, meanB, stdB, nB);
    rc = run_macro('ttest_power', meanA, stdA, nA, meanB, stdB, nB, tpw);
    if rc = 0 then return(tpw);
    else return(.);
   endsub;

run; 

最后,我们可以尝试在数据步骤中使用此功能:

options cmplib=work.funcs;

data test;
   input a s1 n1 a2 s2 n2;
   pw_tmp=ttest_power_fun(a, s1, n1, a2, s2, n2);
 cards;
0 1 10 0 1 10
0 1 10 1 1 10
;
run;

proc print data=test;

答案 1 :(得分:2)

你不能做你想做的事情。 SAS中的宏与典型的编程语言略有不同:它们不是您可以调用的子例程,而只是生成其他SAS代码的代码。由于无法在数据步骤中运行proc power,因此无法从数据步骤运行此宏。 (想象一下,将宏中的所有代码复制到数据步骤中 - 它不会起作用。这就是SAS中的宏所做的。)

做你想做的事的一种方法是一次从tmp读一个观察,然后运行proc power。我会做这样的事情:

/* First count the observations */
data _null_;
  call symputx('nobs',obs);
  stop;
  set tmp nobs=obs;
run;

/* Now read them one at a time in a macro and call proc power */
%macro power;
  %do j=1 %to &nobs;
    data _null_;
       nrec = &j;
       set tmp point=nrec;
       call symputx('meanA',meanA);
       call symputx('stdA',stdA);
       call symputx('nA',nA);
       call symputx('meanB',meanB);
       call symputx('stdB',stdB);
       call symputx('nB',nB);
       stop;
    run;

   proc power; 
     twosamplemeans test=diff_satt 
     groupmeans = &meanA | &meanB 
     groupstddevs = &stdA | &stdB
     groupns = (&nA &nB)
     power = .;    
    ods output Output=pw_out;
  run;

  proc append base=pw_out_all data=pw_out; run;
 %end;
%mend;

%power;

通过使用proc append,您可以存储每轮输出的结果。

我没有检查过这段代码,因此它可能有错误,但这种方法可行。

答案 2 :(得分:2)

您可以使用call execute()从datastep中调用一个调用过程等的宏(如示例),但它可能会有点乱,并且难以调试。