SAS編程-利用宏變量批量構(gòu)建SAS語句

歡迎關(guān)注,SAS茶談!

前面文章SAS編程-小知識:import過程步的Guessingrows選項介紹了導(dǎo)入txt文本的遇到的問題,由于“NA”字符的存在,之前一些本是數(shù)值型的變量導(dǎo)入SAS數(shù)據(jù)集后,變成了字符型變量。

為方便后續(xù)的編程,需要將其轉(zhuǎn)化為字符變量,“NA”的記錄直接賦值為空值。這個在RawData處理中,還是比較常見的。

對于單個變量處理如下:

data test;
  set test0(rename=(var1 = var1_));
  if var1_ ne "NA" then var1 = input(strip(var1_), best.);
  else var1 = .;
run;

如果需要轉(zhuǎn)化的變量較少,依次手動寫程序是沒什么問題的。可一旦變量數(shù)目上去,依次硬寫無疑是一件低效的事情。這時候,考慮利用宏變量批量構(gòu)建SAS語句進行實現(xiàn)。

這篇文章介紹利用宏變量批量構(gòu)建SAS語句,內(nèi)容涉及將一列變量所有值保存到宏變量中。

1. 實現(xiàn)思路

批量構(gòu)建的第一步是,明確完成狀態(tài)下的程序是怎么樣的。不同的實現(xiàn)路徑,批量構(gòu)建的內(nèi)容也不同。

以上面單變量處理為例,rename語句的實現(xiàn)比較單一,直接增加變量賦值等式就好。而if語句的處理就可以有多種,例如,有多少個變量,就對應(yīng)有多少個if語句;例如,通過宏循環(huán)進行處理;例如,通過數(shù)組循環(huán)進行處理。

這里以數(shù)組循環(huán)舉例,演示數(shù)據(jù)集為SASHelp.Class。目標(biāo)是每個數(shù)值型變量+2并轉(zhuǎn)化為字符型變量,并且變量的名稱不變。

SASHELP.CLASS

根據(jù)目標(biāo),思考下程序的大體邏輯:

  1. 為避免變量屬性沖突,需要對原變量名稱Rename;
  2. 新建數(shù)組需要獲取原數(shù)值變量名稱,以及對應(yīng)的Rename語句;
  3. 數(shù)組循環(huán)需要考慮到數(shù)值變量的數(shù)目。

2. 變量信息的獲取

獲取數(shù)據(jù)集的數(shù)值變量名稱,方便后續(xù)構(gòu)建對應(yīng)的SAS語句:

data column;
  set sashelp.vcolumn;                              *;
  where libname = "SASHELP" and memname = "CLASS" and type = "num";
  
  length name_r rename $50;
  name_r = strip(name)||"_";
  rename = strip(name) || " = " || strip(name_r);

  keep name: rename ;
run;

輸出結(jié)果如下:

3. 利用宏變量構(gòu)建SAS語句

最后實現(xiàn)的目標(biāo)程序如下:

data class;
  set sashelp.class(rename=(Age = Age_ Height = Height_  Weight = Weight_));
  
  array num{3} Age_ Height_ Weight_;
  array char{3}  $ 8 Age Height Weight;

  do i = 1 to 3;
    char{i} = strip(put(num{i} + 2, best.));
  end;

  drop Age_ Height_ Weight_ i;
run;

結(jié)合數(shù)據(jù)集以及目標(biāo)程序,我們需要將列內(nèi)容拼接并保存到宏變量中。生成宏變量可以使用Data步和Proc SQL,下面分別以這兩種方法進行實現(xiàn)。

3.1 Data步生成宏變量

在Data步中,可以使用symputx將變量值賦值到宏變量。而整理內(nèi)容的拼接整合,可以通過Retain變量進行實現(xiàn)。內(nèi)容拼接完畢后,在數(shù)據(jù)的最后一行,將值賦值給宏變量。

data tmp;
  set column end=eof;
  length name_m name_r_m rename_m $1000;
  retain name_m name_r_m rename_m " ";
  
  name_m = strip(name_m )||" "||strip(name);
  name_r_m  = strip(name_r_m  )||" "||strip(name_r);
  rename_m = strip(rename_m )||" "||strip(rename);

  if eof then do;
    call symputx("var_char", strip(name_m) );
    call symputx("var_num", strip(name_r_m) );
    call symputx("var_rename", strip(rename_m ) );
    call symputx("n", strip(put(_n_, best.)) );
  end;
run;

%put var_char = &var_char.;
%put var_num= &var_num.;
%put var_rename= &var_rename.;
%put n= &n.;

數(shù)據(jù)集輸出如下:

宏變量輸出如下:

宏變量設(shè)置完畢后,目標(biāo)程序中的特定SAS語句就可以使用宏變量替代。

data class;
  set sashelp.class(rename=(&var_rename.));
  
  array num{&n.} &var_num.;
  array char{&n.}  $ 8 &var_char.;

  do i = 1 to &n.;
    char{i} = strip(put(num{i} + 2, best.));
  end;

  drop &var_num. i;
run;

運行之后,最后的數(shù)據(jù)集處理如下:

這樣處理既實現(xiàn)了既定的效果,同時,也避免了依次單獨處理每個變量。在大批量的變量處理中,這是非常高效的。

3.2 SQL過程步生成宏變量

SQL過程步通過into :子句生成宏變量,具體方法在SAS編程:Proc SQL生成宏變量時INTO子句的使用 中有過介紹,我們需要使用第3種形式:

  1. into : macro-variable(指定一個或多個宏變量)
  2. into : macro-variable-1 ? : macro-variable-n <NOTRIM> (指定一個宏變量序列)
  3. into : macro-variable SEPARATED BY 'characters ' <NOTRIM>指定一個宏變量來保存一列的所有值

具體程序如下:

proc sql noprint;
  select name into: var_char separated by " "  from column;
  select name_r into: var_num separated by " "  from column;
  select rename into: var_rename separated by " "  from column;
  select count(*) into: n from column;
quit;

%put var_char = &var_char.;
%put var_num= &var_num.;
%put var_rename= &var_rename.;
%put n= &n.;

宏變量輸出結(jié)果如下:

與Data步相比,SQL過程步顯得更簡潔,不需要對行記錄進行拼接處理。后續(xù),調(diào)用的宏變量的代碼同Data步,這里不再演示。

總結(jié)

編程中遇到大量同類型的處理需求時,需要考慮批量處理。批量處理的方式有很多,本篇文章使用的方法是將需要的程序元素保存到宏變量中。

生成宏變量可以通過Data步中的call symputx語句,也可以通過SQL中的into :子句。本篇需要將一列變量的所有值保存到宏變量中,通過Data步實現(xiàn)要利用retain語句進行拼接。

感謝閱讀, 歡迎關(guān)注:SAS茶談!
若有疑問,歡迎評論交流!

最后編輯于
?著作權(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)容