我创建了以下宏.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)
你无法以这种方式做你想做的事。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.
我还没有检查过这段代码,所以它可能有错误,但这种方法会起作用。