2015-10-09 47 views
1

我正在尋找一種方法來爲宏參數使用一系列值而不是單個值。我基本上是在連續幾個月裏操作一系列文件(2014年5月到2015年9月),我寫了一個宏來利用命名約定。但是,我仍然手動編寫出使用宏的月份。我從這個月開始用很多不同的文件做了很多次。有沒有辦法讓參數引用一個值列表並像數組/循環一樣通過它們?我已經將%ARRAY看作是一種可能性,但似乎並沒有做我正在尋找的東西,除非我沒有看到它是全功能的。我在下面附上了這段代碼的示例。爲SAS宏參數使用一系列值

%MACRO memmonth(monyr=); 
proc freq data=work.both_&monyr ; 
    table var1/ out=work.mem_&monyr; 
run; 
data work.mem_&monyr; 
    set work.mem_&monyr; 
    count_&monyr=count; 
run; 

%MEND memmonth; 


%memmonth(monyr=may14) 
%memmonth(monyr=jun14) 
%memmonth(monyr=jul14) 
%memmonth(monyr=aug14) 
%memmonth(monyr=sep14) 
%memmonth(monyr=oct14) 
%memmonth(monyr=nov14) 
%memmonth(monyr=dec14) 
%memmonth(monyr=jan15) 
%memmonth(monyr=feb15) 
%memmonth(monyr=mar15) 
%memmonth(monyr=apr15) 
%memmonth(monyr=may15) 
%memmonth(monyr=jun15) 
%memmonth(monyr=jul15) 
%memmonth(monyr=aug15) 
%memmonth(monyr=sep15) 
+0

我將結合MMMYY數據集並使用INDSNAME = variable SET語句選項創建一個新變量。然後你可以運行PROC FREQ BY MONYR;並得到一個數據與所有的計數。 –

回答

1

一般來說,我會推薦將值的列表作爲空格分隔列表並在宏中添加循環邏輯。如果空格是值中的有效字符,則使用其他分隔符。不要使用逗號作爲分隔符,因爲這意味着您需要使用宏引用來調用宏。

所以你的基本宏是這樣的。

%macro memmonth(monyr); 
proc freq data=work.both_&monyr ; 
    table var1/ out=work.mem_&monyr (rename=(count=count_&monyr)) ; 
run; 
%mend memmonth; 
%memmonth(may14) 
%memmonth(jun14) 

您可以將其更改爲此。

%macro memmonth(monyrlist); 
%local i monyr; 
%do i=1 %to %sysfunc(countw(&monyrlist)); 
    %let monyr=%scan(&monyrlist,&i); 
    proc freq data=work.both_&monyr ; 
    table var1/ out=work.mem_&monyr (rename=(count=count_&monyr)) ; 
    run; 
%end; 
%mend memmonth; 
%memmonth(may14 jun14) 

如果您始終想要處理間隔中的所有月份,那麼您可以只傳遞間隔的開始和結束月份。

%macro memmonth(start,end); 
%local i monyr; 
%do i=0 %to %sysfunc(intck(month,"01&start"d,"01&end"d)); 
    %let monyr=%sysfunc(intnx(month,"01&start"d,&i),monyy5.); 
    proc freq data=work.both_&monyr ; 
    table var1/ out=work.mem_&monyr (rename=(count=count_&monyr)) ; 
    run; 
%end; 
%mend memmonth; 
%memmonth(may14,sep15) 

如果您有源列表,無論是文本文件還是數據集,都可以使用簡單的數據步驟來生成宏調用。所以,如果你有變量MONYR輸入數據集,然後你的驅動程序應該是這樣的:

data _null_; 
    set mylist ; 
    call execute(cats('%nrstr(memmonth)(',MONYR,')')); 
run; 

如果源是名稱的文件,然後用適當的INFILE和INPUT語句代替SET語句。如果源是一個目錄名稱,那麼請查看許多SAS方法之一,將目錄中文件的名稱讀入數據集,並使用它來驅動宏調用生成。

+0

這是一個完美的迴應,但我應該更具體。我通過許多不同的程序對許多不同類型的宏執行此操作。有沒有辦法讓它引用外部來源,如文本文件或sas文件?這樣,我只會在月份過去時更新一件事。但是,這也很棒,我可以保留一個文本文件並在每次運行時將其複製粘貼到參數提示中,但仍然可以防止出現一些錯誤。 –

+0

如果我們假設你的宏更加複雜,並且你不想改變它,那麼你需要創建一個驅動程序來收集信息併產生一系列的宏調用。因此,驅動程序可以接受文本文件名稱,它搜索特定模式或SAS數據集的文件的目錄名稱。讓我給這個答案添加一個這樣的選項。 – Tom

+0

這很好,非常感謝。 –