2011-09-13 79 views
11

我創建了以下宏。 Proc power返回包含列Power的表pw_coutdata _null_步驟將pw_out的列Power中的值分配給宏變量tpw。我想宏返回tpw的價值,所以,在主程序中,我可以在數據步這樣稱呼它:宏返回值

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; 

回答

2

你不能做你想要這樣做的事情。 SAS中的宏與典型的編程語言有一些不同:它們不是可以調用的子例程,而只是生成其他執行代碼的代碼。由於您不能在數據步驟中運行proc power,因此無法從數據步驟運行此宏。 (想象一下,將宏內的所有代碼複製到數據步驟 - 這是行不通的,這就是SAS中的宏所做的)。

一種方法可以從tmp一次一個,然後運行proc電源。我會這樣做:

/* 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您可以存儲每輪輸出的結果。

我還沒有檢查過這個代碼,所以它可能有一個錯誤,但這種方法將工作。

10

@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; 
2

您可以調用一個調用pr使用調用execute()方法從datastep中獲取數據(例如示例),但它可能會有點混亂且難以調試。