|
楼主

楼主 |
发表于 2011-6-25 22:43:50
|
只看该作者
Expanding PROC EXPAND
From LCChien's blog on blogspot
原文載點:<a href="http://support.sas.com/resources/papers/proceedings11/417-2011.pdf"><!-- m --><a class="postlink" href="http://support.sas.com/resources/papers/proceedings11/417-2011.pdf">http://support.sas.com/resources/papers ... 7-2011.pdf</a><!-- m --></a><br /><br />PROC EXPAND 程序是 SAS/ETS 裡面其中一個語法,提供許多跟時間相關資料的簡便處理。比方說,將日資料累加成月資料,月資料累加成季資料或年資料,也可以倒過來把季/年資料變成月資料,月資料變成日資料。若遇到缺漏值,該程序可用內插法將資料補齊。也可進行諸如moving average的資料轉換。Bruce Gilsen 在 2011 年的 SAS Global Forum 發表了一篇技術文件,介紹了兩個用 PROC EXPAND 運作的例子。<br /><br /><a name='more'></a><b>Calculate an un-weighted quarterly average from monthly data</b><br /><br />第一個例子介紹如何將月資料轉成季資料。使用的範例資料如下(部分):<br /><pre><code> Obs date id income<br /> 1 20070101 1 1<br /> 2 20070201 1 2<br /> 3 20070301 1 15<br /> 4 20070401 1 4<br /> 5 20070501 1 5<br /> 6 20070601 1 12<br /> 7 20070701 1 7<br /> 8 20070801 1 8<br /> 9 20070901 1 9</code></pre><br />程式如下:<br /><pre><code>proc expand data=one out=two <span class="Apple-style-span" style="color: red;">from=month to=quarter</span> ;<br /> id date;<br /> by id;<br /> <span class="Apple-style-span" style="color: blue;">convert income / method=aggregate observed=average</span>;<br />run;</code></pre><br />紅色部分的 from=month to=quarter 顧名思義就是把資料從月(month)轉成季(quarter)。藍色部分表示轉換的變數為 income,方法為累加(aggregate),最後求出"非加權"平均值(average)。結果如下:<br /><pre><code> Obs id date income income<br /> (expected result)<br /> 1 1 2007:1 6.1333 6<br /> 2 1 2007:2 6.9780 7<br /> 3 1 2007:3 7.9891 8</code></pre><br />最後一欄income(expected result)便是所求,不過程式也會把加權後的結果一併列出,即為倒數第二欄的結果。加權的方式是用天數為基準。以第三季(七~九月)結果來看,前三個月的天數分別是31, 31, 30。總計為92天,因此加權平均後的結果是<br /><pre><code>((31 * 7) + (31 * <!-- s8) --><img src="{SMILIES_PATH}/icon_cool.gif" alt="8)" title="Cool" /><!-- s8) --> + (30 * 9)) / 92 = 7.9891</code></pre><br /><b>Convert weekly data to a monthly average when the weekly values represent values for seven days</b><br /><br />先看一下範例:<br /><pre><code> Obs date id income<br /> 1 20070530 1 11<br /> 2 20070606 1 30<br /> 3 20070613 1 50<br /> 4 20070620 1 70<br /> 5 20070627 1 90<br /> 6 20070704 1 50<br /> 7 20070711 1 40<br /> 8 20070718 1 120<br /> 9 20070725 1 80<br /> 10 20070801 1 100<br /> 11 20070808 1 5<br /> 12 20070815 1 7<br /> 13 20070822 1 9<br /> 14 20070829 1 11<br /> 15 20070905 1 24</code></pre><br />將週資料轉成月資料的方法同第一個範例:<br /><pre><code>proc expand data=one out=two from=<span class="Apple-style-span" style="color: red;">week </span>to=<span class="Apple-style-span" style="color: red;">month </span>;<br /> id date;<br /> by id;<br /> convert income / observed=average;<br />run;</code></pre><br />結果如下:<br /><pre><code> Obs id date income income<br /> (expected result)<br /> 1 1 JUN2007 57.093 60<br /> 2 1 JUL2007 75.905 80<br /> 3 1 AUG2007 18.852 12</code></pre><br />只要把 from=quarter 改成 from=week 即可。但是加權平均income的數據,是用插補法先將週四至下週二的數據進行插補,然後再做平均。作者提供另一種作法:<br /><pre><code>data two;<br /> set one;<br /> do dailydate = date-6 to date;<br /> output; /* transform each weekly observation to 7 daily observations */<br /> end;<br /> run;<br />proc expand data=two out=three from=day to=month ;<br /> id dailydate;<br /> by id;<br /> convert income / observed=average;<br />run;</code></pre><br />這個作法是先將原始的週資料用複製的方法將沒有數字的天數補齊,如下所示:<br /><pre><code> Obs dailydate id income<br /> 1 20070524 1 11<br /> 2 20070525 1 11<br /> 3 20070526 1 11<br /> 4 20070527 1 11<br /> 5 20070528 1 11<br /> 6 20070529 1 11<br /> 7 20070530 1 11<br /> 8 20070531 1 30<br /> 9 20070601 1 30<br /> 10 20070602 1 30<br /> 11 20070603 1 30<br /> 12 20070604 1 30<br /> 13 20070605 1 30<br /> 14 20070606 1 30<br /> 15 20070607 1 50<br /> 16 20070608 1 50<br /> 17 20070609 1 50<br /> 18 20070610 1 50<br /> 19 20070611 1 50<br /> 20 20070612 1 50<br /> 21 20070613 1 50<br /> 22 20070614 1 70<br /> 23 20070615 1 70<br /> 24 20070616 1 70<br /> 25 20070617 1 70</code></pre><br />然後再把這個日資料換算成月資料即可。<br /><br /><b><span class="Apple-style-span" style="font-size: large;">Contact information</span></b><br />Bruce Gilsen<br />Federal Reserve Board<br />Mail Stop 157<br />Washington, DC 20551<br />e-mail: <!-- e --><a href="mailto:bruce.gilsen@frb.gov">bruce.gilsen@frb.gov</a><!-- e --><br />phone: 202-452-2494.<div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6268919072942670865-1616952410225347325?l=sugiclub.blogspot.com' alt='' /></div> |
|