|
楼主

楼主 |
发表于 2011-4-14 14:31:14
|
只看该作者
Improving Your Statistical Consulting Prowess by Adding R to
From LCChien's blog on blogspot
原文載點:http://support.sas.com/resources/papers/proceedings10/290-2010.pdf<br /><br />我不清楚有多少人和我一樣,用SAS分析資料,但是用R來做圖。其實我一開始堅持資料分析和做圖都在SAS內一次完成,但後來我終於明白SAS/GRAPH要做出等同用R畫出來的圖形品質,需要花費更多時間,於是我終於將做圖的工作完全交付給R,也展開了我要一直切換兩個軟體視窗的日子。但我一直相信可以在SAS裡面呼叫R來完成畫圖的工作,終於讓我在SAS Global Forum 2010上面發現到一篇技術文件,在此跟大家分享。<br /><br /><a name='more'></a>首先要讓SAS執行R的程式所需的第一件事情,是要去SAS官網下載SAS/IML Studio 3.2,這是一套龐大但免費的軟體,總容量是整整1GB,下載前需要去SAS官網註冊帳號,註冊好就可以直接下載了。網址是 <a href="http://support.sas.com/rnd/app/da/workshop.html"><!-- m --><a class="postlink" href="http://support.sas.com/rnd/app/da/workshop.html">http://support.sas.com/rnd/app/da/workshop.html</a><!-- m --></a><br /><div style="text-align: center;"></div><div style="text-align: -webkit-auto;"><br /></div>原文內雖然是說用SAS/IML Workshop 2.2,但我實際去官網查詢的結果,發現只有 SAS/IML Workshop 2.1的連結,而且沒有辦法用在最新的SAS 9.2版上面。所以請直接去下載SAS/IML Studio 3.2版即可。經過我的測試是可以執行以下的範例的。<br /><br />下載完畢並安裝好後,就可以在SAS裡面寫R的程式並呼叫R來執行,而結果會顯示在SAS的視窗裡面。不過根據本人的經驗,事情沒有那麼簡單,因為當我裝好並執行一段官網上的範例時,視窗一直彈跳出軟體找不到R的錯誤訊息,經過與SAS官網客服人員的聯繫,才知道SAS/IML Studio 3.2目前只能與R的2.9.1和2.11.1這兩個版本相容。如果你已經安裝了最新的R 2.12.2版,目前唯一的解決方法就是移除最新版然後降級安裝成2.11.1版。如果你有某些特殊的函式比需要在R 2.12.2版才能執行,則必須再次安裝最新版的R才行。<br /><br />所有的R程式,必須要用"submit /R;"開頭,用"endsubmit;"結尾。而以往在SAS裡面常用的注解符號"*"也必須換成井字符號"#"。在進行資料分析前,得先將SAS資料轉成R可以用的資料格式,可利用下面這段程式碼進行轉檔;<br /><pre><code>run ExportDataSetToR("libname.dataname", "R_dataname");</code></pre>其中libname是寫SAS library的名稱,而dataname自然就是SAS資料的名稱。R_dataname則是填入資料集在R裡面所用的名稱。作者建議儘量少用底線當做用在R裡面的資料名稱,因為有可能會出問題。此外,如果是用自定的library,則必須照舊先在一開始用libname語法宣告自定library的路徑。底下的範例因為都是用SAS內部已經建好的Sashelp,所以沒有必要在一開始用libname來宣告。在此需特別注意這一點。以下用幾個範例來說明:<br /><br />範例一;表格<br />這個範例是教如何在SAS裡面使用一些R的指令來整理表格,雖然我覺得SAS在這方面就比R強太多了,但這就是一個範例,程式如下;<br /><br /><pre><code>run ExportDataSetToR("Sashelp.cars", "cars");<br />submit /R;<br />library(Hmisc, T); <br />sink("c/sugi2010/car_summaries.txt");<br />car.sum <- summary.formula(DriveTrain ~ Type + Origin + MPG_City + MPG_Highway + Weight + Wheelbase + Length, data = cars, method = "reverse", overall = FALSE, test = TRUE,digits = 3, prmsd=TRUE, exclude1 = FALSE, long = TRUE);<br />print(car.sum, test = TRUE,digits = 3, prmsd=TRUE, exclude1 = FALSE, long = TRUE);<br />sink();<br />endsubmit;</code></pre><br />為了顧及一些人不懂R的語法,所以在此稍微解釋一下,之後的範例會省略對R的介紹,有需要的人請自行參照R的線上手冊。<br /><br />第一行就是作資料轉檔的語法,剛剛已經介紹過了。本例是拿Sashelp裡面的一個cars的檔案來做表格。"submit /R;"之後開始就全部都是R的語法了,裡面不會有任何SAS程式,直到最後用"endsubmit;"才是回到SAS語法。library() 是R裡面呼叫某個package的語法,Hmisc就是專門拿來做summary table的package。sink("....txt") 是先定義接下來所有的報表是要輸出到某txt文件裡面,記得結束要補上"sink();"在最後面才會完成存檔動作。summary.formula()就是製作的函數,裡面要放很多參數,在此就不一一介紹了,總之做完的結果是放在car.sum這個物件裡面。而print()是把car.sum這個物件印進剛剛用sink函數建立的純文字檔。而那個純文字檔打開後如下所示;<br /><div class="separator" style="clear: both; text-align: center;"><a href="http://farm6.static.flickr.com/5304/5610404074_214cda7e30.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://farm6.static.flickr.com/5304/5610404074_214cda7e30.jpg" /></a></div><div class="separator" style="clear: both; text-align: center;"></div><br />R繪製出來的圖形相當漂亮,但表格就很陽春,非常像古早PE2打出來的效果。因此這個時候就是SAS展現威能的時候了。用一個data step把那個純文字檔叫進來;<br /><pre><code>data cars2;<br /> infile "("c/sugi2010/car_summaries.txt"" dsd dlm="|" <br /> lrecl=1024 firstobs=5 truncover;<br /> format junk $20. label $34. all $34. front $35. rear $35. test $35. ;<br /> input junk $ label $ all $ front $ rear $ test $ ; <br /> if substr(junk,1,1)="+" then delete;<br /> drop junk;<br />run;</code></pre>其中:<br /><ul><li>用infile把純文字檔呼叫進SAS,用dlm="|"將每一行分段,用lrecl來定義整行最大長度,並用firstobs指定SAS從第五行開始讀。</li><li>用format把剛剛用"|"將每一行切成數段,所以每一段就變成一個變數,因此需要定義變數的格式。在此將所有變數定義成文字格式,因為接下來不用再做分析了,所以只要能列印出及可。</li><li>用input設定各變數的名稱,這些名稱要和format裡面所寫的變數名稱一樣。</li><li>用junk變數把不必要的隔線刪除掉。</li></ul><br />把不要的內容清乾淨後,用ods和proc report把結果印出來;<br /><pre><code>ods rtf file="c:\sugi2010\sas_r\car_summaries2_09oct20b.rtf" ;<br />title "Summaries by treatment group";<br />proc report data=cars2 nowindows;<br /> columns label all front rear test;<br />run; ods rtf close;</code></pre>結果如下;<br /><div class="separator" style="clear: both; text-align: center;"></div><div class="separator" style="clear: both; text-align: center;"><a href="http://farm6.static.flickr.com/5108/5610410874_f770aec30c_z.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://farm6.static.flickr.com/5108/5610410874_f770aec30c_z.jpg" /></a></div><div class="separator" style="clear: both; text-align: center;"></div><br />範例二;繪圖<br />在SAS裡面用R畫圖是我比較關心的,但和上面這個範例比起來並沒有太多不同。程式如下;<br /><pre><code>run ExportDataSetToR("Sashelp.CARS", "cars");<br />submit /R;<br /><span class="Apple-style-span" style="color: blue;">library(Hmisc, T); </span><br /><span class="Apple-style-span" style="color: blue;">## Create data frame – cars2 – dropping cars with 3, missing, and 5 cylinders; </span><br /><span class="Apple-style-span" style="color: blue;">cars2 <- cars[cars$Cylinders>3 & !is.na(cars$Cylinders) & cars$Cylinders != 5,] </span><br /><span class="Apple-style-span" style="color: blue;">## place cars2 in search path </span><br /><span class="Apple-style-span" style="color: blue;">attach(cars2); </span><br /><span class="Apple-style-span" style="color: blue;">## Create summary data sets for Highway and city gas mileage MPG by number of </span><br /><span class="Apple-style-span" style="color: blue;">cylinders and origin. ; </span><br /><span class="Apple-style-span" style="color: blue;">## Bootstrap resampling used to calculate 95% confidence intervals of mean; </span><br /><span class="Apple-style-span" style="color: blue;">mean.hw <- summarize(MPG_Highway, llist(Cylinders, Origin), smean.cl.boot); </span><br /><span class="Apple-style-span" style="color: blue;">mean.city <- summarize(MPG_City, llist(Cylinders, Origin), smean.cl.boot); </span><br /><span class="Apple-style-span" style="color: blue;">## rename MPG_Highway and MPG_City to common name: mean.mpg.; </span><br /><span class="Apple-style-span" style="color: blue;">mean.hw2 <- upData(mean.hw, rename=list(MPG_Highway="mean.mpg")); </span><br /><span class="Apple-style-span" style="color: blue;">mean.city2 <- upData(mean.city, rename=list(MPG_City="mean.mpg")); </span><br /><span class="Apple-style-span" style="color: blue;">##create new variable type to label type of mean.mpg; </span><br /><span class="Apple-style-span" style="color: blue;">mean.hw2$type[mean.hw2$mean.mpg>0]<- "Highway" </span><br /><span class="Apple-style-span" style="color: blue;">mean.city2$type[mean.city2$mean.mpg>0]<- "City" </span><br /><span class="Apple-style-span" style="color: blue;">## Vertical combine of the 2 data frames – new dataframe is named all; </span><br /><span class="Apple-style-span" style="color: blue;">all <- rbind(mean.hw2, mean.city2);</span><br /><span class="Apple-style-span" style="color: blue;">## Use Hmisc function xYplot to plot mean gas mileage and 95% confidence intervals; </span><br /><span class="Apple-style-span" style="color: blue;">## by cylinders with separate panels for each of 3 origins. ; </span><br /><span class="Apple-style-span" style="color: blue;">## groups – separate curves by type within each panel.; </span><br /><span class="Apple-style-span" style="color: blue;">## col = c(1,2) sets colors for 2 groups (1=black, 2=red). Lty sets line types; </span><br /><span class="Apple-style-span" style="color: blue;">## layout=c(3,1) determines number of rows and columns – c(3,1) is 3 columns and 1 </span><span class="Apple-style-span" style="color: blue;">row; </span><br /><span class="Apple-style-span" style="color: blue;">xYplot(Cbind(mean.mpg, Lower, Upper) ~ Cylinders | Origin, data=all, groups=type, </span><br /><span class="Apple-style-span" style="color: blue;">col=c(1,2), lty=c(1,2), layout=c(3,1), type='o'); </span><br />endsubmit;</code></pre><br />基本上你只要把前兩行和最後一行先在SAS裡面寫好,然後在第三行前面貼上R的程式即可。不過上面這段用R繪圖的語法,其實在SAS裡面是可以直接做的,下面是兩個軟體畫出來的圖形的比較;<br /><div class="separator" style="clear: both; text-align: center;"><a href="http://farm6.static.flickr.com/5022/5609833345_ee0e342efd_z.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://farm6.static.flickr.com/5022/5609833345_ee0e342efd_z.jpg" /></a></div><br /><div class="separator" style="clear: both; text-align: center;"></div>左圖是用R畫出來的圖,右邊是用SAS畫的。乍看之下好像右圖比較好,但那是因為新版的SAS剛好有PROC SGPANEL這個程序把所有繪圖參數都最佳化了,如果遇到PROC SGPANEL沒有支援的圖形,那就不要太指望SAS能給你甚麼好圖了。而根據本人實際測試的結果,其實還是R做的圖比較好看,所以就大膽地在SAS/IML Studio底下執行R的程式吧!<br /><br /><b>CONTACT INFORMATION </b><br />Name: Jeff Gossett<br />University of Arkansas for Medical Sciences. Department of Pediatrics.<br />One Children's Way <br />Little Rock, AR 72202<br />Work Phone: 501-364-6631<br />Fax: 501-364-1431<br />E-mail: <!-- e --><a href="mailto:GossettJeffreyM@uams.edu">GossettJeffreyM@uams.edu</a><!-- e --><br />Web: <!-- m --><a class="postlink" href="http://www.arpediatrics.org/research/biostatistics">http://www.arpediatrics.org/research/biostatistics</a><!-- m --><div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6268919072942670865-3245684446823300171?l=sugiclub.blogspot.com' alt='' /></div> |
|