R軟體for迴圈的迷思
許多人認為學會過了程式設計,就能夠駕馭R 語言!殊不知R 語法有其特殊性,更遑論背後的統計模型與繪圖專業了。舉例來說,下面就是標準的不良R 程式(canonical bad Rprogram),用來計算a 與b 兩向量的內積:
> (a <- 1:5)
[1] 1 2 3 4 5
> (b <- 5:1)
[1] 5 4 3 2 1
> d <- NULL
> for ( i in 1:length(a)) {
+ d[i] <- a[i] * b[i]
+ }
>d
[1] 5 8 9 8 5
> s <- 0
> for (i in 1:length(d)) {
+ s <- s+d[i]
+ }
> s
[1] 35
傳統的兩次迴圈設計,當資料量大時,會大幅影響執行時間。其實善用R 的向量化(vectorization)特性,一到兩行的指令即可快速輕易地算出向量內積了。(註:因資料量很小,此例感受不到速度的差異!)
> (d <- a * b)
[1] 5 8 9 8 5
> (s <- sum(a * b)
[1] 35
以程式執行效率的觀點來看,R的世界非不得已 (指當無法運用apply系列函數與vectorization特性時) 才會使用for迴圈。
撰文者: |
R軟體的寬資料與長資料
當我們對單一資料蒐集對象測量多個變數值時,寬資料是指同一對象的所有測量值都排在同一列;長資料則是各個測量值單獨成一列,並標明其是哪個變數的測量值。某些統計分析須使用寬資料,例如相關分析;也有些分析偏好長資料,例如變異數分析。
首先,我們以data.frame 函數建一個五個蒐集對象、三個變數的寬資料:
> mydata <- data.frame(var1 = c(12, 15, 19, 22, 15), var2 = c(18, 12, 42, 29, 44), var3 = c(8, 17, 22, 19, 31))
>mydata
運用stack 函數可將資料轉成長資料,
> sdata <- stack(mydata)
> sdata
stack 函數還可使用select 參數選擇要轉換成長資料的變數,此處我們選var1 和var2。
> sdata <- stack(mydata, select = c(var1, var2))
讀者可利用下列指令檢查長資料十筆數據中均無var3!
>sdata$in == "var3"
[1] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
反過來說,unstack 函數可將長資料轉換為寬資料,要注意的是必須使用R 中的公式符號(formula notation) 'values ~ ind',此處解讀為依不同的ind 值將values 歸類。最後,對於更複雜的長寬資料格式轉換,讀者可運用R 中的reshape 套件,這個部分容後再敘。
> mydata <- unstack(sdata, values ~ ind)
> head(mydata)
參考資料:Spector, P. (2008), Data Manipulation with R, Springer.
撰文者: |
R軟體應用於機率密度曲線與累積分配曲線的繪製
機率與統計的教科書都會有機率密度函數(probability density function, pdf) 與累積分配函數(cumulative distribution function, cdf)的圖形,以說明累積機率值與分位點(quantile)的對應關係。在R 中,讀者可以pnorm 函數求出某一分位點的累積幾率值。例如:標準常態分位點z = 1.5 的累積機率值如下。
> pnorm(1.5, 0, 1)
[1] 0.9331928
反過來說,qnorm 可以求出累積機率為0.9331928 所對應的標準常態分位點。
> qnorm(0.9331928, 0, 1)
[1] 1.5
為了讓讀者深刻瞭解前述的對應關係,先以R 中的curve 函數繪製標準常態的密度曲線:
> curve(dnorm(x, 0, 1), xlim = c(-3, 3), main = "Area to left of 1.5 = pnorm(1.5, 0, 1)")
再利用多邊形繪製函數polygon,連接密度相當高的點(橫座標從-3 到1.5)形成灰色陰影區域,並在適當的位置加上說明文字。
> cord.x <- c(-3, seq(-3, 1.5, 0.01), 1.5)
> cord.y <- c(0, dnorm(seq(-3, 1.5, 0.01)), 0)
> polygon(cord.x, cord.y, col = "grey")
> text(-0.5, 0.1, "area=pnorm(1.5,0,1)")
>text(1.5, 0.02, "1.5=qnorm(0.9331928, 0 ,1)")
同樣地,R 可繪製累積分配函數的圖形,再利用abline 函數加上適當的水平與垂直線、以及說明文字。走筆至此,冀望讀者能感受到R 強大且高品質的繪圖輸出,更多的繪圖功能容後再敘。
> curve(pnorm(x, 0, 1), xlim = c(-3,3), main = "F(z)=P(Z<=z)")
> abline(h = 0.9331928, lty = 2)
> abline(v = 1.5, lty = 3)
> text(-2, 0.85, "pnorm(1.5) is 0.9331928")
> text(1.5, 0.02, "qnorm( 0.9331928) is 1.5")
參考資料:
Verzani, J. (2001), simpleR – Using R for Introductory Statistics, The CSI MathDepartment, City University of New York.
撰文者: |