|
楼主

楼主 |
发表于 2011-3-2 05:14:51
|
只看该作者
So Many Variables; Too Many Labels, Moving Labels from One V
From LCChien's blog on blogspot
原文載點:<a href="http://support.sas.com/resources/papers/proceedings10/047-2010.pdf"><!-- m --><a class="postlink" href="http://support.sas.com/resources/papers/proceedings10/047-2010.pdf">http://support.sas.com/resources/papers ... 7-2010.pdf</a><!-- m --></a><br /><br />在 SAS 資料處理的過程中,使用者會發現,當複製一個變數並給予新的變數名稱時,舊變數的格式雖然會一併複製到新變數裡面,但舊變數的 label 卻沒有辦法複製過去。若只有一兩個變數時還可以用手動的方式在 data step 裡面重打,但若變數過多時,這就會成為一個相當棘手的問題。John Ladds 提供了一個簡易的方式來解決這個 label 複製的問題。<br /><br /><a name='more'></a>以下面這個資料集當作範例:<br /><code><pre>proc format;<br /> value OriginalOrderAgree<br /> 1 = 'Strongly agree'<br />2 = 'Somewhat agree'<br />3 = 'Neither agree nor disagree'<br />4 = 'Somewhat disagree'<br />5 = 'Strongly disagree'<br />6 = 'Not applicable'<br /> 97 = "Don't know"<br />99 = 'Not stated';<br /> value ReverseOrderAgree<br /> 5 = 'Strongly agree'<br />4 = 'Somewhat agree'<br />3 = 'Neither agree nor disagree'<br />2 = 'Somewhat disagree'<br />1 = 'Strongly disagree'<br /> other='Missing';<br />run;<br />** Create some test data;<br />data work.theData;<br /> input @01 id $10.<br /> @11 Q001 2.<br /> @13 Q002 2.<br /> @15 Q003 2.<br /> @17 Q004 2.<br /> @19 Q005 2.<br /> @21 Q006 2.<br /> @23 Q007 2.<br /> @25 Q008 2.<br /> @27 Q009 2.<br /> @29 Q010 2.;<br /> label Q001 = "Have material's and equipment I need";<br /> label Q002 = "Material and tools avail in lang choice";<br /> label Q003 = "I use the language of my choice";<br /> label Q004 = "My jobs fits my interests.";<br /> label Q005 = "I have support at work.";<br /> label Q006 = "I am satisfied, current work arrangement";<br /> label Q007 = "I can claim overtime";<br /> label Q008 = "Overall, I like my job.";<br /> label Q009 = "I get satisfaction from my work.";<br /><br /> label Q010 = "I know how my work contributes";<br />format Q001-Q010 OriginalOrderAgree.;<br />datalines4;<br />1234567890 1 2 3 4 5 6 1 2 3 4;<br />1234567892 2 3 4 5 1 1 2 3 4 5;<br />1234567893 3 4 5 1 2 2 2 3 5 1;<br />1234567894 4 5 1 2 3 3 3 3 1 2;<br />1234567895 5 1 2 3 4 4 4 4 2 3;<br />1234567896 1 2 3 4 5 5 5 5 3 4;<br />1234567897 2 3 4 5 1 1 1 1 4 5;<br />1234567898 3 4 5 1 2 2 2 2 5 1;<br />1234567899 4 598 2 3 3 3 3 1 2;<br />123456781099 199 3 4 4 4 5 2 3;<br />;;;;<br />run;</pre></code><br />根據這個資料集,裡面有十個變數,從Q001~Q010,每個變數為數據「1,2,3,4,5」。現在假設要製造新變數R_Q001~R_Q010,而這些新變數是將就舊變數的數據倒轉過來,也就是 1 變成 5,2 變成 4,...,5 變成 1。於是作者利用下面這個 macro 來處理這段:<br /><code><pre>%macro reverseValueOrder(Q=,Qfmt=);<br /> select(&Q.);<br /> when(1) R_&Q.=5;<br /> when(2) R_&Q.=4;<br /> when(3) R_&Q.=3;<br /> when(4) R_&Q.=2;<br /> when(5) R_&Q.=1;<br /> otherwise R_&Q.=.;<br /> end;<br /> ** Transfer the questions label to the new variable;<br /> <b><span class="Apple-style-span" style="color: red;">if eof then call execute("label R_&Q.="||'"'||strip(vlabel(&Q.))||'";');</span></b><br /> ** Add the new value labels to the new variable;<br /> format R_&Q. &Qfmt..;<br />%mend reverseValueOrder;</pre></code><br />其中,「select(&Q);.....end;」主要就是在做變數倒轉的工作,而下面有一行「if...then...」搭配「call execute」便是在處理 label 複製的動作。裡面的 vlabel 函數的作用是將舊變數裡面的 label 給列出來,放在 strip 函式後面主要是移除不必要的空格,並確保 vlabel 函式叫出來的 label 是字串形式。<br /><br />接著就可以在新的 data step 裡面一邊進行數據倒轉的工作,一邊進行搬移 label 的工作,如下所示:<br /><code><pre>data work.thedata;<br /> set work.theData <b><span class="Apple-style-span" style="color: red;">end=eof</span></b>;<br />** Open the post DATA STEP Processing;<br /><b><span class="Apple-style-span" style="color: red;">if eof then call execute('data &syslast.; set &syslast.;'); </span></b><br />**A. My Job World ;<br /> %reverseValueOrder(Q=Q001, Qfmt=ReverseOrderAgree);<br /> %reverseValueOrder(Q=Q002, Qfmt=ReverseOrderAgree);<br /> %reverseValueOrder(Q=Q003, Qfmt=ReverseOrderAgree);<br /> %reverseValueOrder(Q=Q004, Qfmt=ReverseOrderAgree);<br /> %reverseValueOrder(Q=Q005, Qfmt=ReverseOrderAgree);<br /> %reverseValueOrder(Q=Q006, Qfmt=ReverseOrderAgree);<br /> %reverseValueOrder(Q=Q007, Qfmt=ReverseOrderAgree);<br /> %reverseValueOrder(Q=Q008, Qfmt=ReverseOrderAgree);<br /> %reverseValueOrder(Q=Q009, Qfmt=ReverseOrderAgree);<br /> %reverseValueOrder(Q=Q010, Qfmt=ReverseOrderAgree);<br />;... ... ... ... ... ... ... ... ... ... ... ** <br />** Close the post DATA STEP Processing;<br /><b><span class="Apple-style-span" style="color: red;">if eof then call execute ('run;');</span></b><br />run;</pre></code><br />特別提醒的地方有三個。一是 set 後面一定要加上「end=eof」字樣。二是執行 macro 前加上「if eof then call execute('data &syslast.; set &syslast.;'); 」,目的是確保程式執行的資料是當前資料。所以記得在運作此程式之前,別去跑其他不相干的資料。三是結束前加上「if eof then call execute ('run;');」,這樣就大功告成了。<div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6268919072942670865-7497945167349595128?l=sugiclub.blogspot.com' alt='' /></div> |
|