宏返回一个值

hun*_*gtx 12 sas sas-macro

我创建了以下宏.Proc power返回pw_cout包含列的表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;
Run Code Online (Sandbox Code Playgroud)

这是宏的代码:

%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;
Run Code Online (Sandbox Code Playgroud)

Ani*_*iko 11

@itzy指出为什么你的方法不起作用是正确的.但是,维修器材的方法的精神的解决方案:你需要创建一个功率计算功能uisng PROC钙镁磷肥.事实上,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;
Run Code Online (Sandbox Code Playgroud)

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

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; 
Run Code Online (Sandbox Code Playgroud)

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

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;
Run Code Online (Sandbox Code Playgroud)


itz*_*tzy 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;
Run Code Online (Sandbox Code Playgroud)

By using proc append you can store the results of each round of output.

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