公告

[公告]
2014/01/17
由於已經是faculty的關係,不太有足夠時間寫部落格。因此更新的速度會相當緩慢。再加上近幾年來SAS GLOBAL FORUM沒有出現讓我覺得驚艷的技術文件,所以能分享的文章相對也減少許多。若有人推薦值得分享的SAS技術文件,請利用『問題討論區』告知。

2013/07/19
臉書留言板的功能因為有不明原因故障,因此特此移除。而intensedebate的留言板因管理不易,也一併移除。目前已經開啟內建的 G+ 留言系統,所以請有需要留言的朋友,可直接至『問題討論區』裡面留言。


2007年12月23日 星期日

The TRANPOSE Procedure or How to Turn It Around

原文載點:http://www2.sas.com/proceedings/sugi31/234-31.pdf

資料轉置的工作,在 SAS 裡算是一門相當深奧的學問,也有許多不同的方法可以完成。PROC TRANSPOSE 是 SAS 內建的資料轉置程序,特別是將直的資料轉成橫的,更能顯現其威力。Janet Stuelpner 在 SUGI 31 中針對 PROC TRANSPOSE 程序做了一點概略的介紹,同時也剖析了一些使用上的變化,使用者可依照其不同的需求進行調整。

首先做點名詞解釋。所謂的直的資料(vertical data)長的是這個樣子:


而橫的資料(horizontal data)則是長的像這個樣子:


不過之後的範例所使用的資料是這個:


先用最簡單的程式來看結果會是什麼:
proc transpose data=vitals; run;
proc print; run;


這個 PROC TRANSPOSE 程序完全沒有呼叫任何 statement,則 SAS 會將整個資料以右上角為支點,像翻書一樣把資料往右上角做一百八十度的翻動。則結果會像下圖所示:



有上圖可見,經過轉置後,所有的變數被放在一個叫做 _NAME_ 的新變數底下。所有標籤則是被放在新變數 _LABEL_ 底下。至於轉置後的數據,SAS 則是自動從 COL1 開始命名直到最後。

如果想要針對這些新變數進行重新命名,可以直接從 PROC TRANSPOSE 程序來進行,不需要另外開一個 data step 來修改。程式如下所示:
proc transpose data=vitals label=DESC name=VAR prefix=VAL;
run;


這個程式多了三個 options。 label 即是用來替 _LABEL_ 重新命名,name 則是用來替 _NAME_ 從新命名,而 prefix 則是將 COL1 到 COL11 開頭的 COL 重新命名。

重新命名後的資料呈現如下圖:


如果需要針對一些類別變數內各層進行資料轉置,可使用 BY statement 來完成。範例程式如下:
proc transpose data=vitals label=DESC name=VAR prefix=VAL;
by protocol inv pat;
run;


此程式一次把三個類別變數 protocol、inv 和 pat 放進 BY statement 裡,則 SAS 會先對這三個變數排序歸類,然後再依照不同的層級進行資料轉置。結果如下圖:



也可以針對特地變數使用 VAR statement 進行轉置:
proc transpose data=student  out=s1  prefix=info;
by name;
var class grade credit;
run;


結果如下:


不過不建議這種轉法,尤其當變數屬性不同時,因為這樣很容易造成轉置後的新變數屬性產生混亂。

如果想要替轉置後的新變數用比較有意義的方式重新命名,而非使用 prefix 做單純但無意義的命名,則可以使用 ID statement 來完成這項工作。此處使用一個新的資料:
data student;
input name $1-10 class $12-18 grade $20 @@;
cards;
Ann Adams CHEM101 A
Ann Adams MATH101 A
Ann Adams LIT100 B
Ann Adams PHY101 A
Ann Adams FREN100 B
Ann Adams LAB B
Ann Adams SPAN200 .
Bob Benz CHEM101 B
Bob Benz MATH101 A
Bob Benz LIT100 A
Bob Benz PHY101 C
Bob Benz FREN100 B
Bob Benz LAB B
Bob Benz SPAN200 C
Carl Jones CHEM101 B
Carl Jones MATH101 .
Carl Jones LIT100 A
Carl Jones PHY101 C
Carl Jones FREN100 C
Carl Jones LAB A
Carl Jones SPAN200 .
run;


程式如下:
proc transpose data=student;
by name;
var grade;
id class;
run;


結果如下:


明顯的可以發現,SAS 自動地將原本 ID statement 底下的 class 變數變成了轉置後新變數的名稱了。

AUTHOR CONTACT
Janet Stuelpner
Left Hand Computing, Inc
326 Old Norwalk Road
New Canaan, CT 06840
(203) 966-7520 voice
(203) 966-8027 fax
jstuelpner@usa.net
CODE { display: block; /* fixes a strange ie margin bug */ font-family: Courier New; font-size: 8pt; overflow:auto; background: #f0f0f0 url(http://klcintw.images.googlepages.com/Code_BG.gif) left top repeat-y; border: 1px solid #ccc; padding: 10px 10px 10px 21px; max-height:200px; height:200px; // for IE6 line-height: 1.2em; }