SAS編程-利用宏變量批量構建SAS語句

歡迎關注啄骇,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并轉化為字符型變量扔涧,并且變量的名稱不變园担。

SASHELP.CLASS

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

  1. 為避免變量屬性沖突枯夜,需要對原變量名稱Rename弯汰;
  2. 新建數(shù)組需要獲取原數(shù)值變量名稱,以及對應的Rename語句湖雹;
  3. 數(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種形式:

  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.;

宏變量輸出結果如下:

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

總結

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

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

感謝閱讀屠凶, 歡迎關注:SAS茶談!
若有疑問肆资,歡迎評論交流矗愧!

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子唉韭,更是在濱河造成了極大的恐慌夜涕,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,277評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件属愤,死亡現(xiàn)場離奇詭異女器,居然都是意外死亡,警方通過查閱死者的電腦和手機住诸,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,689評論 3 393
  • 文/潘曉璐 我一進店門驾胆,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人贱呐,你說我怎么就攤上這事丧诺。” “怎么了奄薇?”我有些...
    開封第一講書人閱讀 163,624評論 0 353
  • 文/不壞的土叔 我叫張陵驳阎,是天一觀的道長。 經(jīng)常有香客問我馁蒂,道長呵晚,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,356評論 1 293
  • 正文 為了忘掉前任沫屡,我火速辦了婚禮劣纲,結果婚禮上,老公的妹妹穿的比我還像新娘谁鳍。我一直安慰自己,他們只是感情好劫瞳,可當我...
    茶點故事閱讀 67,402評論 6 392
  • 文/花漫 我一把揭開白布倘潜。 她就那樣靜靜地躺著,像睡著了一般志于。 火紅的嫁衣襯著肌膚如雪涮因。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,292評論 1 301
  • 那天伺绽,我揣著相機與錄音养泡,去河邊找鬼。 笑死奈应,一個胖子當著我的面吹牛澜掩,可吹牛的內容都是我干的。 我是一名探鬼主播杖挣,決...
    沈念sama閱讀 40,135評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼肩榕,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了惩妇?” 一聲冷哼從身側響起株汉,我...
    開封第一講書人閱讀 38,992評論 0 275
  • 序言:老撾萬榮一對情侶失蹤筐乳,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后乔妈,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體蝙云,經(jīng)...
    沈念sama閱讀 45,429評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,636評論 3 334
  • 正文 我和宋清朗相戀三年路召,在試婚紗的時候發(fā)現(xiàn)自己被綠了勃刨。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,785評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡优训,死狀恐怖朵你,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情揣非,我是刑警寧澤抡医,帶...
    沈念sama閱讀 35,492評論 5 345
  • 正文 年R本政府宣布,位于F島的核電站早敬,受9級特大地震影響忌傻,放射性物質發(fā)生泄漏。R本人自食惡果不足惜搞监,卻給世界環(huán)境...
    茶點故事閱讀 41,092評論 3 328
  • 文/蒙蒙 一水孩、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧琐驴,春花似錦俘种、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,723評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至牢酵,卻和暖如春悬包,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背馍乙。 一陣腳步聲響...
    開封第一講書人閱讀 32,858評論 1 269
  • 我被黑心中介騙來泰國打工布近, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人丝格。 一個月前我還...
    沈念sama閱讀 47,891評論 2 370
  • 正文 我出身青樓撑瞧,卻偏偏與公主長得像,于是被迫代替她去往敵國和親显蝌。 傳聞我的和親對象是個殘疾皇子季蚂,可洞房花燭夜當晚...
    茶點故事閱讀 44,713評論 2 354

推薦閱讀更多精彩內容