2017年11月18日 星期六

R | ggplot: Regression Line & Grouping

這篇要講的是在圖上加趨勢線(regression line)和 grouping。需要用到下面的東西,先安裝吧。

library(ggplot2)
library(nlme)
library(dplyr)
library(gapminder)

重新開 R Studio 的話,要重跑一次 ggplot2,不然會顯示沒有這個 function。

課堂講義請參考這篇:R Graphics with Ggplot2 - Day2

加趨勢線用的是: geom_smooth()

geom_smooth() 預設的方法(method)是 loess,也就是 Local Polynomial Regression Fitting。

下面先比較檔案資料 mpg 裡面的參數 hwy 和 displ 的關係。

#1
ggplot(mpg, aes(displ, hwy)) +
            geom_point() + geom_smooth()



灰色的部分是 confidence intervals (CI),如果不想要的話,就加 se = FALSE

ggplot(mpg, aes(displ, hwy)) +
            geom_point() +
            geom_smooth(se = FALSE)

如果你想要的是 liner regression (lm),可以加: method = "lm" 

加了 method 的話就會覆蓋住(override)原本預設的 loess,如果沒加的話,呈現的就是預設的 loess。

#2
ggplot(mpg, aes(displ, hwy)) + geom_point() +
                               geom_smooth(method = "lm")



另外還有 robust linear regression (rlm),但這個需要裝 library(MASS)

ggplot(mpg, aes(displ, hwy)) + geom_point() +
                               geom_smooth(method = "rlm")



在這裡解釋一下,這些圖的語法可以把它分成兩層來想,第一層是 ggplot(),第二層是 geom_point() 和 geom_smooth()。第二層的 geom_smooth 跟 geom_point 同樣是獨立的,可以分開用,也可以合在一起用,所以兩個的 y-axis 用的 variables 可以不一樣。在第二層裡設的東西會覆蓋住第一層的。

在上面的例子裡,第二層的 variables 都沒有另外指定,所以都是第一層裡設的 y-axis,也就是 hwy,圖裡呈現的趨勢線也是依照 hwy 的數據畫出來的。但是,趨勢線也可以設定為另外的 variable。

在下面的例子裡,我們把第二層用不同的 variables 設定,點的部分用 cyl 分組以不同顏色顯示(在這邊把 cyl 設成 factor,不懂的話請看上篇),然後趨勢線設成 cty 的。

#3
ggplot(mpg, aes(displ, hwy)) +
            geom_point(aes(colour = factor(cyl))) +
            geom_smooth(aes(y = cty))



上圖顯示的點是依照 cyl 分不同顏色,但趨勢線是依照 cty 畫的。(可以和圖 #1 做比較)

如果把 factor 設在第一層 ggplot(),那點圖和趨勢線沒特別設定的話,會依第一層的分組,例如下面的點和趨勢線都是照 cyl 分成四種,但趨勢線的 y 設定為 cty 覆蓋了第一層的 hwy,所以是 cty 的現,而不是 hwy 的線。

#4
ggplot(mpg, aes(displ, hwy, colour = factor(cyl))) +
            geom_point() +
            geom_smooth(aes(y = cty))



想要更清楚分層的話,可以把第一層 ggplot() 設為一個 object,其他的再加在後面。

例如,可以把:

ggplot(mpg, aes(displ, hwy)) +
            geom_point(aes(colour = factor(cyl))) +
            geom_smooth(method = "lm")

變成這樣:

#5
p1 <- ggplot(mpg, aes(displ, hwy))
p1 + geom_point(aes(colour = factor(cyl))) +
     geom_smooth(method = "lm")



在這個例子裡,p1 只有最基本 x 和 y 軸有設定,其他的部分再另外加,例如在點的部分用 factor 的參數以不同顏色分組,上圖的參數是 cyl。因為加的部分是獨立的,所以在點設的不會影響到趨勢線的,趨勢線的部分因為沒設,所以還是依照第一層(p1)的,也就是 hwy。如果在 geom_smooth 那邊用 factor 設定顏色的話,趨勢線就會依 factor 分組,線也會跟著 factor 換顏色。

#6
p1 + geom_point(aes(colour = factor(cyl))) +
     geom_smooth(aes(colour = factor(cyl)), method = "lm")



我們把點的設定拿掉,看看會變成怎樣。

#7
p1 + geom_point() +
     geom_smooth(aes(colour = factor(cyl)), method = "lm")



和圖六比較,有發現什麼不同嗎?圖六因為點也是依照 cyl 分顏色的,所以有 4, 5, 6, 7 四組,但是因為 5 的部分只有兩個點,所以其實沒有線的部分,當你把點的設定拿掉只剩趨勢線時,cyl 裡面 5 的那個就消失了。

我們再跳回圖 #6,如果圖 #6 沒設成 linear regression 的話,就是這樣:

#8
p1 + geom_point(aes(colour = factor(cyl))) +
     geom_smooth(aes(colour = factor(cyl)))



因為圖 #6 和圖 #8 在點和趨勢線的部分都有設 colour = factor(cyl),我們可以把第一層設成這樣:

p2 <- ggplot(mpg, aes(displ, hwy, colour = factor(cyl))
p2 + geom_point() +
     geom_smooth()

可以和圖 #4 相比較,圖四的趨勢線是設 cty 而不是 hwy,而圖 #8 因為沒在第二層 geom_smooth 指定另外的 variable,所以是依照第一層(p1)的 hwy 畫的趨勢線。

第四張圖如果同樣分層的話,會設成這樣:

p2 <- ggplot(mpg, aes(displ, hwy, colour = factor(cyl)))

p2 + geom_point() +
     geom_smooth(aes(y = cty))

看出來了嗎?這樣分層比較有沒有比較清楚了呢?

如果你想改趨勢線的顏色,跟前一篇介紹的一樣,要用 color = ' '

#9
p2 + geom_point() +
     geom_smooth(method = "lm", color = 'black')



在上圖中,因為把趨勢線設為黑色,所以覆蓋住第一層的 colour = factor(cyl),因此是依照 hwy 畫出的單一趨勢線,而非照 cyl 分開畫的線。

這個情況下,也可以用 grouping 的功能畫趨勢線,出來的結果會跟上面的圖 #9 相同,不需要設線的顏色。用的語法是 group =

p2 + geom_point() +
     geom_smooth(aes(group = 1), method = "lm")



再來,我們跳回圖 #7,如果我們想依 cyl 的參數畫趨勢線,但不想分顏色的話,也可以用 grouping 的功能。

#10
p1 + geom_point() +
     geom_smooth(aes(group = factor(cyl)), method = "lm")



接著,我們試試把 p2 的顏色換成用形狀表示:shape = ()

#11
p3 <- ggplot(mpg, aes(displ, hwy, shape = factor(cyl)))

p3 + geom_point() + geom_smooth(method = "lm")



用上面 p3 的設定,把趨勢線也依照 cyl 用顏色區分。

#12
p3 + geom_point() +
     geom_smooth(aes(colour = factor(cyl)), method = "lm")



可以讓圖更複雜,連點都用不同的 variables 分類。XD

p3 + geom_point(aes(colour = drv)) +
     geom_smooth(aes(colour = factor(cyl)), method = "lm")



最後,我們來嘗試一下繼續試一下 grouping,就是在圖。

用的檔案資料是 Oxboys,在 library(nlme) 裡面,下面比較身高和年齡的關係,然後用 Subject 來分類。

#13
ggplot(Oxboys,aes(age,height, colour = Subject)) +
              geom_point()



接下來,我們要用線條把相同的 Subject 連起來,也就是把同顏色的點用線連起來,所以需要用到 geom_line(),然後用 Subject 分組。這裡跟圖 #10 同樣用 group =

#14
ggplot(Oxboys,aes(age,height)) +
              geom_point(aes(colour = Subject)) +
              geom_line(aes(group = Subject), alpha = 0.3)



geom_line() 裡面的 alpha = 0.3 是指透明度,介於 0 和 1 之間,數字越小越透明(顏色越淡),可用在點和線,這個之後也會講到。

如果不用 group 的功能的話,可以像上面的方式一樣用 colour =

#15
ggplot(Oxboys,aes(age,height)) +
              geom_point() +
              geom_line(aes(colour = Subject), alpha = 0.6)




最後,來做個練習吧。

Using the gapminder dataset (library(gapminder)), make a line graph of life expectancy of each country over time. Colour countries by the continent.

ggplot(gapminder, aes(year, lifeExp))
       geom_line(aes(color = continent), alpha = 0.3) +
       geom_smooth(linetype = 2)



趨勢線的型態也可以用 linetype =  設定,有這幾種:

0 = blank, 1 = solid, 2 = dashed, 3 = dotted, 4 = dotdash, 5 = longdash, 6 = twodash

因此,也可以這樣設:geom_smooth(linetype = "dashed")









沒有留言:

張貼留言

歡迎發表意見