這部分取決於您的宏在做什麼。如果我們假設你的宏正在做一些旨在在數據步之外運行的東西(即它不只是分配一個數據步變量),那麼你有幾個選擇。
調用execute已經解釋過,是某些情況下,一個很好的選擇。但是,它有一些缺點,特別是對於宏觀時序,在某些情況下需要特別注意保護 - 尤其是當您在宏中創建宏變量時。 Quentin在他的評論中展示了一種解決這個問題的方法(將%NRSTR
添加到調用中),但是我發現當使用其他方法有優勢時,我更喜歡只使用CALL EXECUTE - 特別是,如果我想使用SAS數據步驟技術(例如FIRST或LAST,或者某種形式的循環)來創建我的宏調用,或者我必須在數據步驟中執行某些操作,並且可以避免再次讀取文件的開銷。如果我只是像上面一樣寫數據步驟 - 數據,設置,調用執行,運行 - 我不會使用它。
PROC SQL SELECT INTO
通常是我用於列表處理(這主要是這是什麼)。在處理不太複雜的事情時,我喜歡SQL的簡單性,例如,只需使用DISTINCT
即可輕鬆獲得每個宏調用的一個版本,而無需明確編寫proc sort nodupkey
或使用first/last處理。它還具有調試的優點,即您可以將所有宏調用寫入結果窗口(如果不添加noprint
),如果我試圖瞭解爲什麼這會比日誌更容易閱讀我的電話沒有得到正確生成(並且沒有任何額外的PUT語句)。
proc sql;
select catx(',','%macro(',arg1,arg2,arg3)||')'
into :mvarlist separated by ' '
from dataset;
quit;
&mvarlist.
它運行得很簡單,沒有時間問題(因爲你只是寫了一堆宏調用)。
這種方法的主要缺點是在宏變量中最多有64k個字符,所以如果你寫了大量的這些,你會遇到這種情況。在這種情況下,使用CALL EXECUTE
或%INCLUDE
文件。
%INCLUDE
文件在很大程度上是有用的或者作爲替代,當通話結束字符限制,或者如果你發現有一個文本文件,看您的通話(如果你正在運行這個有用SELECT INTO
例如,在批處理模式下,這可能比日誌或列表輸出更容易進行和/或解析)。您只需將呼叫寫入文件,然後%INCLUDE
即可。
filename myfile temp; *or a real file if you want to look at it.;
data _null_;
set dataset;
file myfile;
put @1 catx(',','%macro(',arg1,arg2,arg3)||')';
run;
%include myfile;
我真的不使用這個多了,但它是由舊的SAS程序員那麼好知道特別常用的技術。
DOSUBL
是一個相對較新的方法,並在一定程度上可以用來代替CALL EXECUTE
爲它的默認行爲是典型的接近你期望直觀地比CALL EXECUTE
的東西。 doc頁面對於這種工作原理是不同的最好的例子。基本上,它通過讓每個單獨的調用看起來導入並將宏變量從/調用到調用環境來修復時序問題,這意味着每個迭代DOSUBL
都在不同的時間運行,而在CALL EXECUTE
處運行的是一切,宏環境是'固定的'(即,任何對宏變量的引用在運行時都是固定的,除非你用%NRSTR
亂搞)。
還有一兩件事值得一提的是RUN_MACRO
,該FCMP
語言的一部分。這使您可以完全運行宏並將其內容導回到數據步,在某些情況下這是一個有趣的選項(例如,您可以圍繞選擇某項內容的PROC SQL打包調用,然後將其作爲變量導入數據集,全部在一個datastep中)。如果你這樣做是爲了調用一個宏來分配一個數據步驟變量,而不是運行一個不需要導入數據步驟的進程,但是這是值得考慮的事情,如果你確實希望這些數據全部返回到調用該進程的數據集中。
來源
2014-08-28 15:13:14
Joe
提到的那樣非常好的總結。我仍然希望更多的文檔將來自SAS re DOSUBL和RUN_MACRO。在我看來,這兩種方式都以某種方式在單獨的迷你SAS會話中執行代碼。當幾年前我玩過它的時候,範圍規則並不是很清楚。例如,使用run_macro調用的宏中設置的系統選項可能會或可能不會更改主會話的選項。但他們肯定是強大的工具,值得學習。 – Quentin 2014-08-28 16:37:04
很好的答案。另外值得考慮的是,宏可以改寫爲FCMP函數嗎? – 2014-08-28 16:49:10
我期待着FCMP函數超過宏的那一天...儘管在這種情況下,它聽起來像是一個完整的分析,現在可能最好不要這樣寫(儘管RUN_MACRO允許它以這種方式寫入,如果沒有其他重大利益,我不相信這真的是個好主意)。 – Joe 2014-08-28 17:10:49