歡迎關注啄骇,SAS茶談!
前面文章SAS編程-小知識:import過程步的Guessingrows選項介紹了導入txt文本的遇到的問題哑姚,由于“NA”字符的存在,之前一些本是數(shù)值型的變量導入SAS數(shù)據(jù)集后吕座,變成了字符型變量专缠。
為方便后續(xù)的編程,需要將其轉化為字符變量捂龄,“NA”的記錄直接賦值為空值释涛。這個在RawData處理中加叁,還是比較常見的。
對于單個變量處理如下:
data test;
set test0(rename=(var1 = var1_));
if var1_ ne "NA" then var1 = input(strip(var1_), best.);
else var1 = .;
run;
如果需要轉化的變量較少唇撬,依次手動寫程序是沒什么問題的它匕。可一旦變量數(shù)目上去窖认,依次硬寫無疑是一件低效的事情豫柬。這時候,考慮利用宏變量批量構建SAS語句進行實現(xiàn)扑浸。
這篇文章介紹利用宏變量批量構建SAS語句烧给,內容涉及將一列變量所有值保存到宏變量中。
1. 實現(xiàn)思路
批量構建的第一步是喝噪,明確完成狀態(tài)下的程序是怎么樣的创夜。不同的實現(xiàn)路徑,批量構建的內容也不同仙逻。
以上面單變量處理為例,rename
語句的實現(xiàn)比較單一涧尿,直接增加變量賦值等式就好系奉。而if
語句的處理就可以有多種,例如姑廉,有多少個變量缺亮,就對應有多少個if
語句;例如桥言,通過宏循環(huán)進行處理萌踱;例如,通過數(shù)組循環(huán)進行處理号阿。
這里以數(shù)組循環(huán)舉例并鸵,演示數(shù)據(jù)集為SASHelp.Class。目標是每個數(shù)值型變量+2并轉化為字符型變量扔涧,并且變量的名稱不變园担。
根據(jù)目標,思考下程序的大體邏輯:
- 為避免變量屬性沖突枯夜,需要對原變量名稱Rename弯汰;
- 新建數(shù)組需要獲取原數(shù)值變量名稱,以及對應的Rename語句湖雹;
- 數(shù)組循環(huán)需要考慮到數(shù)值變量的數(shù)目咏闪。
2. 變量信息的獲取
獲取數(shù)據(jù)集的數(shù)值變量名稱,方便后續(xù)構建對應的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;
輸出結果如下:
3. 利用宏變量構建SAS語句
最后實現(xiàn)的目標程序如下:
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;
結合數(shù)據(jù)集以及目標程序摔吏,我們需要將列內容拼接并保存到宏變量中鸽嫂。生成宏變量可以使用Data步和Proc SQL纵装,下面分別以這兩種方法進行實現(xiàn)。
3.1 Data步生成宏變量
在Data步中溪胶,可以使用symputx
將變量值賦值到宏變量搂擦。而整理內容的拼接整合,可以通過Retain變量進行實現(xiàn)哗脖。內容拼接完畢后瀑踢,在數(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ù)集輸出如下:
宏變量輸出如下:
宏變量設置完畢后橱夭,目標程序中的特定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種形式:
- into : macro-variable(指定一個或多個宏變量)
- into : macro-variable-1 ? : macro-variable-n <NOTRIM> (指定一個宏變量序列)
- 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.;
宏變量輸出結果如下:
與Data步相比,SQL過程步顯得更簡潔预鬓,不需要對行記錄進行拼接處理巧骚。后續(xù),調用的宏變量的代碼同Data步格二,這里不再演示劈彪。
總結
編程中遇到大量同類型的處理需求時,需要考慮批量處理顶猜。批量處理的方式有很多沧奴,本篇文章使用的方法是將需要的程序元素保存到宏變量中。
生成宏變量可以通過Data步中的call symputx
語句长窄,也可以通過SQL中的into :
子句扼仲。本篇需要將一列變量的所有值保存到宏變量中,通過Data步實現(xiàn)要利用retain
語句進行拼接抄淑。
感謝閱讀屠凶, 歡迎關注:SAS茶談!
若有疑問肆资,歡迎評論交流矗愧!