2015-11-25 287 views
0

我開始學習SAS中的%macro,現在我試圖用直方圖作爲輸出來實現簡單的引導程序。SAS中的Bootstrap宏

/*Create K data sets(vectors)*/ 
%macro datasets(K); 
    %do i=1 %to &K; 
     data indata&i; 
      %do j = 1 %to 50; 
      x=(rand('normal',2,9)); 
      output; 
      %end; 
     run; 
    %end; 
%mend datasets; 

%datasets(3); 

/*Bootstrap and hist*/ 
%macro boot (data,res); 
    %do i=1 %to &res; 
     %let x = (sample(&data,50)); 
     %let m = (mean(&x)); 
    %end; 
    proc iml; 
     read &m into A; 
     create DataM from A; 
     append from A; 
     close Data1; 
    quit; 
    proc univariate data=Data1; 
    histogram m; 
    run; 
    %mend boot; 
%boot(Indata1,100); 

它不工作,我不明白爲什麼。你能指出我的錯誤嗎?

+0

你期望在這裏發生什麼:'%let x =(sample(&data,50)); %let m =(平均值(&x));'我希望這不符合你的期望,它只是創建宏變量,並且不會進行任何抽樣或計算 – Reeza

+0

@Reeza我試圖在沒有'% let'並且它不起作用 – Art

+0

你期望在這些步驟中發生了什麼?另外,請參閱本白皮書以獲取有關如何在SAS中引導的參考資料:http://www2.sas.com/proceedings/forum2007/183 -2007.pdf – Reeza

回答

0

正如前面提到的使用Proc SurveySelect和Proc Means。您可以在一個Proc SurveySelect中選擇全部100個樣本,然後將一個BY語句應用Proc Means來計算一步中的平均值。宏在此處不添加任何內容。

我發佈了兩個解決方案 - 宏解決方案的確需要更長的時間。

*Without macro; 
proc surveyselect data=indata1 out=rsample method=srs n=50 reps=100; 
run; 

proc means data=rsample noprint; 
by replicate; 
var x; 
output out=Data1 mean(x)=m; 
run; 

proc univariate data=Data1; 
histogram m; 
run; 

*Macro solution; 

%macro boot(data, res); 
%do i=1 %to &res; 

%*Currently pulls the same sample every time but you can fix that part; 
proc surveyselect data=&data out=x method=srs n=50 reps=1 seed=343434; 
run; 

proc means data=x noprint; 
var x; 
output out=m mean(x)=m; 
run; 

proc append base=DataM data=m; 
run; 

%end; 

%mend; 

%boot(Indata1,10); 
+0

我嘗試了不同的方法來改變種子(作爲做循環的函數),但它仍然拉同一個樣本。 – Art

+0

發佈一個新問題。在proc surveyselect中更改種子應該改變你的樣本。 – Reeza

1

使用PROC SURVEYSELECT生成引導樣本,然後通過複製(由SURVEYSELECT創建的變量)進行引導分析。你的宏觀想法太慢了。

+0

重點在於使用%宏編寫bootstrap。我對R和SAS做了同樣的處理,但現在我想用%宏編寫它。目前代碼的速度對我來說並不重要。 – Art

0

如果我們概述一些發佈的宏代碼不起作用的方法,這可能會有所幫助。如果沒有別的,那麼作爲事情的例子,以避免。

如果第一個宏,%datasets(),您使用的是宏觀%DO循環,你應該用一個正常的數據一步DO循環。還要確保將本地宏變量定義爲本地。這將防止宏修改具有相同名稱的現有宏變量的值。

/*Create K data sets(vectors)*/ 
%macro datasets(K); 
    %local i ; 
    %do i=1 %to &K; 
    data indata&i; 
     do j = 1 to 50; 
     x=(rand('normal',2,9)); 
     output; 
     end; 
     drop j; 
    run; 
    %end; 
%mend datasets; 

在第二個宏中,你有一個%DO循環,它什麼都不做。

%do i=1 %to &res; 
    %let x = (sample(&data,50)); 
    %let m = (mean(&x)); 
%end; 

您重複多次完全相同的%LET語句。結果不會改變,因爲循環變量i根本沒有被引用。如果你用data=indata1調用宏,那麼這兩個語句的結果將是X = (sample(indata1,50)),而那個M = (mean((sample(indata1,50))))。我認爲,也許你打算字符串samplemean可能會採取一些措施,但由於它們沒有宏觸發器(&%),它們只是宏處理器的字符流。

我不是IML方面的專家,但這些陳述看起來並不像他們所做的那樣。