第76講 SAS中常用的Macro List技巧

2021-12-28 小叮噹講SAS和Python

SAS在臨床試驗中用得比較多的是SAS Base, SQL, STAT等模塊。還有比較高級的編程就是Macro, 都說比較牛逼的SAS programmer是Macro用得比較好的。今天就講講臨床那些常用的宏技巧。記得前面第19講講過一些宏函數與宏程序,有興趣的可以回顧一下。這裡再講一些SAS Macro作為補充。

1.宏變量列表

* 創建宏變量;

proc sql noprint;

    select count(distinct name)

        into:N

           from sashelp.class;

 

    select distinct name

        into :varname1 - :varname%left(&N)

           from sashelp.class;

 

    select distinct name

        into:varlist separated by ' ", " '

           from sashelp.class;

quit;

 

%put &N;

%put &varname1;

%put &varname19;

%put "&varlist"; 這裡不加引號會報錯

%put %bquote(&varlist); 可以加上%bquote函數屏蔽引號,不出錯。

日誌輸出如下:

84   %put &N;

19

85   %put &varname1;

Alfred

86   %put &varname19;

William

87   %put "&varlist";

"Alfred", "Alice", "Barbara", "Carol", "Henry", "James", "Jane", "Janet", "Jeffrey", "John", "Joyce", "Judy", "Louise", "Mary",

"Philip", "Robert", "Ronald", "Thomas", "William"

 關於宏變量列表裡面元素的個數還有一種求法:

%let N = %sysfunc(countw(&varlist));

%put &N;

19

 這樣雖然N求對了,但是日誌還是有錯,不完美。

所以這裡涉及到引號的問題。需要用到%bquote函數來屏蔽引號。

 

%let N = %sysfunc(countw(%bquote(&varlist)));

%put &N;

19

我們先來看一個簡單的例子,按照條件拆分數據集。

data Alfred;

    set sashelp.class;

    if name = "Alfred" then output Alfred;

run;

再來看一個宏程序,遍歷宏變量列表每個元素。

%macrosplit;

    %global i;

    %do i =%to %sysfunc(countw(%bquote(&varlist)));

        data &&varname&i;

           set sashelp.class;

               if name = "&&varname&i" then output                                                &&varname&i;

        run;

    %end;

%mend;

%split

巧妙的是%sysfunc(countw(%bquote(&varlist)))前面不用帶解析符號&。

2.遍歷宏變量列表

(1)找出列表最後一個元素

%macro listlast(list);

   %scan(&list,-1,%str(","));因為之前&varlist宏變量是以", "為分隔符的,所以這裡%str(", "),括號裡面是specific delimiter

%mend listlast;

%put %listlast(%bquote(&varlist));

結果是 William

3.得到宏變量列表其中一個具體元素

%let var2 = %scan(%bquote(&varlist),2,%str(","));

%put &var2;

結果是 Alice

4.遍歷宏變量列表所有元素

%macro scanlist(list);

data a;

    %do i=%to &N;

        var&i = "%scan(&list,&i,str(","))";

    %end;

run;

%mend;

%scanlist(%bquote(&varlist));

5.%do %until 遍歷宏變量列表所有元素

proc contents data=sashelp.class out=class noprint;

run;

proc sort data=class out=vars(keep=name);

    by varnum;

run;

proc sql noprint;

    select distinct name

        into :varlist separated by' '

           from vars;

quit;

%put &varlist;

 

%macro countvar(list);

     %global cnt;

     %leti = 1;

     %do %until (%scan(&list,&i,%str())=%str());

        %global var&i;

        %let var&i = %scan(&list,&i,%str());

        %let i = %eval(&i + 1);

     %end;

     %let cnt = %eval(&i-1);

%mend;

%countvar(&varlist)

%put &cnt;

%do %while 遍歷宏變量列表所有元素

%macro wordcount(list);

   %local cnt;

   %let cnt=0;

   %do %while (%qscan(&list,&cnt+1,%str()) ne %str());

      %let cnt = %eval(&cnt+1); 

   %end;

   &cnt

%mend;

%put %wordcount(&varlist);

宏函數%superq的理解

data_null_;

    call symputx('xxx','&A&B&C&D');

    call symputx('A','IF');

    call symputx('B','I');

    call symputx('C', 'WERE');

    call symputx('D', 'YOU');

    call symputx('IfIwereYou', 'I want to go ...');

run

%put %superq(&xxx);

大家猜結果會是什麼,對,就是I want to go ...,可以看出這裡xxx是一個宏變量,加上&就是每遇到能夠解析的&就不斷的解析下去,直到最後的宏變量不能解析為止。

%cmpres函數

%let text = %str(   The  quick  brown  fox jumped  over   the lazy   dog  );

%put text= %cmpres(&text);

結果是:The quick brown fox jumped over the lazy dog

全部壓縮成一個空格。

給一個空格分隔符的列表變成 引號逗號引號 為分隔符的列表,感覺這種功能以後用到很有用。

%macro qstr(list);

%str(%')%qsysfunc(tranwrd(%cmpres(&list),%str(),

%str(%', %')))%str(%')

%mendqstr;

 

optionsnomprint;

%put %qstr(www   baidu);

%put %qstr(www.baidu.com   org);

日誌:

'www', 'baidu'

'www.baidu.com', 'org'

像Python一樣將列錶轉化為集合:集合裡面的元素具有唯一性(無重複)。

%macro DistinctList(list);

   %local dlist i;

   %let dlist = %scan(&list,1,%str());   

   %let i=2; 

   %do %while(%scan(&list,&i,%str()) ne %str());  

      %if %sysfunc(indexw(&dlist,%scan(&list,&i,%str())))=0%then%do;

         %let dlist = &dlist %scan(&list,&i,%str());

      %end;

      %leti = %eval(&i+1);  

   %end;

   &dlist

%mend;    

 

%let list=name name sex sex height height;

%put %distinctlist(&list);

name sex height

好了,今天的宏技巧就分享到這裡了,上面幾個宏主要講解宏變量列表的一些操作,熟練運用這些技巧,在實際工作中會很有用的,其實宏技巧遠不止這些,SAS官網有很多講解宏的相關書籍(配套data與code)可供大家學習。如果上面關於宏有不懂的童鞋,歡迎一起交流討論。今天就講到這裡啦。。(^_^)



 

 

 

 



相關焦點

  • SAS-Macro 中的那些語句(一)
    可以理解成和其它程式語言中的變量一樣,在內存中創建了一個空間(給這個空間一個標記,宏變量的名稱),然後將一些值放到這個內存空間中(這就是定義宏變量的過程),好吧,我是一個不善解釋的人,沒理解的還是自行百度領悟。那麼就來看看如何來定義Macro變量。%let 方式定義宏變量:這個是最簡單、最直接的賦值定義的方式.
  • SAS MACRO-基礎
    /*(1)定義好一個macro之後,sas會自動保存在 work.sasmacr*//*mstored:將下面的宏存儲在永久性邏輯庫(libds)裡面,*//*邏輯庫名稱:libds*/options mstored sasmstore=libds;%macro macro-name/store <source>; macro-text;%mend macro-name;/*(2)了解宏定義、語法、宏指令是否正確、大小輸出到日誌裡面*/option mcompilenote=all|none;
  • SAS-Macro 中的那些語句(二)
    答案也是有的,和其它的程式語言中的變量是一樣的,SAS中的宏變量是分局部宏變量與全局宏變量...由於小編經驗不足,可能會理解錯,還請見諒與指正。;%mend;/*執行宏前的宏變量的值*/%put NOTE:第一個解析值(宏外):&macvar1.;/*執行宏中的宏變量的值*/%test;/*執行宏後的宏變量的值*/%put NOTE:第三個解析值(宏外):&macvar1.;看上面的代碼:先猜猜的以此解析的三個宏變量的值是啥...
  • 10個常用的SAS技巧
    今天分享幾個常用的,初學者容易忽略的SAS編程小技巧。1.讓SAS也能用中文變量名默認的SAS命名規則是無法使用中文等特殊字符作為SAS名,不過我們可以通過validvarname=any系統選項,突破此限制,不僅如此,我們甚至可以通過validmemname=extend系統選項突破數據集名稱的限制。
  • SAS-輸出文檔生成目錄的方法
    在SAS中,利用ODS輸出文檔前,通常都會定義Style。通過proc template定義輸出樣式,在proc template中也可以對目錄頁的樣式進行設置。proc template中相關的語句如下。
  • 50個SAS常用函數,收藏!
    Returns the first nonmissing value from a list of numeric character arguments.coalescec('','a','z') → 『a』. coalescec('','','') → 『』(missing). coalescec('c1','c2') → 『c1』.
  • SAS巖論 | Macro系列(3)——運行機制
    macro,或者修改別人的SAS macro,開發自己的SAS macro時,總是碰到倆類問題:這樣的問題和那樣的問題。究其原因,還是基礎不夠紮實,如果能夠耐下心來,對SAS macro運行機制多做一些了解,情況也許會好很多。本節內容,推薦程度:※※※※※SAS Macro作為SAS高手不可或缺的一項技能,是因為它功能足夠強大,能極大的提升程序開發效率;使你的時間和精力投入在更有價值的事情上。
  • 乾貨 SAS學習途徑與相關資源——SAS商業分析
    SAS可能是分析行業最常用的工具了。與其他工具比如R和Python相比,儘管有人可能對它的可持續性以及特徵有著不同的想法,但是有兩點是可以肯定的。那就是:這兩個理由足夠讓剛剛進入這個行業的新手考慮學習SAS。
  • 匯總|SAS編程及應用中的技巧和方法
    sas數據整理常用小技巧:1、修改屬性 attrib2、根據條件刪除記錄
  • 驚呆了,sas還可以這樣之iml進階
    例如打開一個數據集後當前觀測為第0條觀測,而如果用list命令或者用read命令進行操作時,當前觀測改變為第1條觀測。第一個數據集是整個sashelp.class,第二個數據集是從sashelp.class,的第十條開始讀,即sashelp.class,中的第十條就是當前數據集的第一條。
  • Python模型完美切換SAS,還能這麼玩..
    大家都知道,Python 和 SAS 是兩個很常用的數據挖掘工具。Python 開源、免費、有豐富的三方庫,一般在網際網路公司廣泛使用。而SAS需付費,且費用較高,一般網際網路公司無法承擔,更多的是在銀行等傳統金融機構中使用,不過這兩年由於Python太火,原本使用SAS的也開始逐漸轉向Python了。
  • 常用的sas時間函數介紹
    上一篇文章中講的是input和put的用法,主要寫的也是關於用put和input用於時間的轉化,但是注意的是,put和input,不僅僅只用於之間轉化,這部分內容之前沒有顧及到,在後續的內容中會更新到,請大家見諒。今天更新的內容是sas在日常處理中使用到的時間函數。
  • 技巧|SAS常見實用技巧大匯總
    Scan函數提出以空格或標點符號隔開的第n個單詞。不同於trim,trim只是提取字符。【功能】從字符表達式s中搜取給定的n個單詞【類別】 字符函數【語法】1. Scan(s,n) n為正數時,從字符s末尾提取n個字符2. Scan(s,n) n為負數時,從字符s開始提取n個字符3.
  • SAS ADV 認證經驗分享
    (comment的內容不能執行),  後面macro的內容是一個proc print的語句,最後執行這個macroproc print data=certadv.lab9;proc print data=certadv.lab9;3、一個loop macro,輸入start和end,在循環中判斷i是否大於10,大於10開始data step
  • 第201講 SAS——retain與數組
    在190講我們知道了幾乎任何程式語言都支持數組,然而SAS裡面的數組有時候常常會被忽略
  • SAS實現批量計算字符型變量的IV值
    前兩篇文章介紹了WOE和IV的使用及計算方式,本篇文章著重介紹下批量對s
  • SAS Advanced全球認證986分--備考經驗分享
    官網上有一個介紹考試界面的視頻,講的很詳細。https://www.sas.com/en_us/certification/credentials/foundation-tools/advanced-programming-professional.html高級部分只考核三大部分內容:SQL、Macro和Advanced techniques。
  • SAS | 單因素logistic回歸
    然而,在臨床預測模型中,如果要用到的是logistics回歸,那麼建議,單因素篩選也建議採用單因素logistic去篩選,目的是方便尋找預測因子。先上效果圖,引用sashelp.heart的數據集核心程序為:proc logistic data=data;    class &var (param=ref ref="ref");;    model y(event="1")=var/parmlabel ;run;既然是單因素,那就只需要改變「var
  • 第146講 SAS—我對SAS PDV與retain的一些理解
    如何不讓新的空值替換原來上一條觀測的臨時值呢,即是LOCF,我們需要在PDV中retain一個新的臨時變量,比如:每次讀取一條觀測值都會output到新數據集class中。直到讀取最後一條觀測,我們可以發現最後PDV的自動變量_N_=20。當指針跳到sashelp.class觀測數為19,不能再往下跳了,指針結束讀取數據,此時PDV自動變量_N_=20, 觀測值初始化為上一條即是第19條的觀測值。即是PDV停留在這歷史的一刻,直到SAS關閉。
  • [SAS在財務研究中的應用]短期事件研究法
    sas),並來信詢問修改方法,可以學習到更多使用的編程邏輯事件研究法的基本研究邏輯,如下圖在進行事件研究法時,首先選定要進行分析的事件,財務會計研究中常選定的事件有股利宣告事件在本例中,我們想了解滬深兩市的事件研究法績效是否會有所差異,所以特別由ian_event中讀入了market這個變量進行合併,接下來進行事件研究法中的第二個宏%ar_test