12

我创建了以下宏。Proc power返回pw_cout包含 column 的表Power。该data _null_步骤将 的 列Power中的值分配pw_out给宏变量tpw。我希望宏返回 的值tpw,以便在主程序中,我可以在 DATA 步骤中调用它,例如:

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

下面是宏的代码:

%macro ttest_power(meanA=, stdA=, nA=, meanB=, stdB=, nB=);


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;

&tpw
%mend ttest_power;
4

3 回答 3

11

@itzy 正确指出了为什么您的方法行不通。但是有一个解决方案可以保持您的方法的精神:您需要创建一个使用 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;
于 2011-09-19T16:30:38.207 回答
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,您可以存储每轮输出的结果。

我没有检查过这段代码,所以它可能有一个错误,但这种方法会起作用。

于 2011-09-13T13:41:58.447 回答
2

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

于 2011-09-21T09:29:20.083 回答