298:global宏變量和local宏變量;宏變量和data步交互-SYMPUTX

一:global宏變量和local宏變量

例子1:

%let outside = AAA; 
%macro one;
  %global inone; 
  %let inone = BBB;
%mend one;
%macro two;
  %let intwo = CCC; 
%mend two;
%macro last;
  %one
  %two
  %put &outside &inone &intwo; 
%mend last;
%last
image.png

注意到outside(屬于global變量)這個宏變量是在宏外面定義的,所以也不需要申明global;

宏變量inone雖然是在宏里面定義的,但是它用global申明了,所以也屬于global宏變量

例子2:

%macro allyr3(start=10,stop=14);
  data allyear;
    set
    %do year = &start %to &stop;
      yr&year(in=in&year)
    %end;;
    year = 2000
    %do year = &start %to &stop;
      + (in&year*&year)
    %end;;
  run;
%mend allyr3;

%let year = FRED;
%put The global value of year is &year;
%allyr3(start=12, stop=14)
%put The global value of year is &year;
image.png

例子3:
在上面的這段代碼中,year的值會被15給代替
所以這種情況下,我們可以對宏里面的year進行申明,這樣就不會導(dǎo)致宏變量之間發(fā)生沖突

*申明local變量,避免宏變量之間沖突;
%macro allyr4(start=10,stop=14);
  %local year; 
  %let year=&start; 

  data allyear;
    set
    %do year = &start %to &stop;
      yr&year(in=in&year)
    %end;;
    year = 2000
    %do year = &start %to &stop;
      + (in&year*&year)
    %end;;
  run;
%mend allyr4;

%let year = FRED;
%put The global value of year is &year;
%allyr4(start=12, stop=14)
%put The global value of year is &year;
image.png

二:宏變量和data步交互

對于數(shù)據(jù)集中的數(shù)據(jù),我們有時候可能想將某個變量的值做成宏變量,比如下面這樣

data age;
set sashelp.class(where=(name='Jane'));
%let jane_age = age;
run;
但是上面這段代碼是不會輸出正確結(jié)果的,原因還是那個宏先編譯的內(nèi)在執(zhí)行機制。

需要注意的是,call symputx并不是宏水平語句,而是一個可執(zhí)行的DATA步驟例程,因此它允許你在data步執(zhí)行的時候,直接根據(jù)數(shù)據(jù)集的變量賦值給宏變量。

CALL SYMPUTX(macro-variable, value <, symbol-table>);

CALL SYMPUTX的第一個參數(shù)可以是字符串、可以是字符變量、也可以是字符型變量和字符串的結(jié)合。

CALL SYMPUTX的第二個參數(shù)可以是字符串、可以是字符變量、也可以是字符型變量和字符串的結(jié)合。

下面我們看下上面的這3種情形:
①:第一和第二個參數(shù)都是字符串,需要注意的是,在將值賦予給宏變量的時候,會自動去除值前后的空格。

image.png

image.png
image.png

可以看到值前后的空格都被自動去除了。

②:第一個和第二個參數(shù)都是變量
說實話,一開始根據(jù)SASHELP的解釋,我根本沒看懂怎么用。下面看例子就清楚了


image.png
image.png
image.png

解釋:當(dāng)?shù)谝粋€參數(shù)是數(shù)據(jù)集中的某個變量的時候,它的值就是宏變量的名稱(在這里就是變量mvar的值"MAIN"和“NUM”,注意不是變量mvar)

第二個參數(shù)就是數(shù)據(jù)集變量的值(在這里就是變量nhigh的值)。

需要注意的是如果第二個參數(shù),變量的值是數(shù)值型的話,SAS會自動先轉(zhuǎn)換成字符型再輸出,還會在log窗口輸出一個note。

還需要注意到是第一個參數(shù)如果是數(shù)據(jù)集的某個變量,那么變量的值必須是字符型或者說符合SAS命名規(guī)則的值,比如mvar都是數(shù)字,SAS就會報錯。

if mod(n,2)=0 then mvar="MAIN";
else mvar=777;

image.png

這就是第二種情況。

③:字符型變量和字符串的結(jié)合;

image.png

這段程序會輸出19個宏變量(數(shù)據(jù)集里面有19條觀測)

image.png

上面是CALL SYMPUTX參數(shù)的解析,講到CALL SYMPUTX,還有一個就是CALL SYMPUT,前者是后者的升級版,主要區(qū)別在于如果第二個參數(shù)是數(shù)值型的,CALL SYMPUTX能直接轉(zhuǎn)換成字符型在進行處理,并且不會在log里報note;

CALL SYMPUTX的第三個參數(shù)能控制生成的宏變量是什么類型的,但是CALL SYMPUT不行。

data _null_;
  x=5;
call symput('x1',x); 
call symput('x2',trim(left(put(x,6.)))); 
call symputx('x3',x); 
run;
%put The vertical bars show leading and trailing blanks.;
%put Using SYMPUT X1 is |&x1|;
%put Using SYMPUT with TRIM LEFT PUT X2 is |&x2|;
%put Using SYMPUTX X3 is |&x3|;
image.png

這條log就是第一個CALL SYMPUT產(chǎn)生的。

除了trim/left函數(shù),還可以通過這種形式生成宏變量:

VAR2="SAS";
call symputx('x4',catt(VAR2," programmer    ")); 
image.png

att函數(shù)的作用是去除末尾的空格,比如下面的程序,輸出結(jié)果是SAS前面的空格也被去除了,但是這是call symputx的功勞,而不是catt的功勞。

VAR2="    SAS";
call symputx('x4',catt(VAR2," programmer    "));

上面這段程序輸出結(jié)果跟上張圖片一樣。

運用catt函數(shù)還需要注意一點,我就不舉例子了。

image.png
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容