R數(shù)據(jù)科學(xué)筆記:3

第四章:工作流:腳本

迄今為止,我們一直使用RStudio 控制臺(tái)來(lái)運(yùn)行代碼添寺。這是一個(gè)非常好的開(kāi)始,但如果需要?jiǎng)?chuàng)建更復(fù)雜的ggplot2 圖形或者dplyr 管道,你很快就會(huì)發(fā)現(xiàn)控制臺(tái)非常不方便吭露。為了拓展工作空間,我們應(yīng)該使用RStudio 腳本編輯器尊惰。要想打開(kāi)腳本編輯器讲竿,可以點(diǎn)擊File 菜單,選擇New File弄屡,接著選擇R Script题禀;也可以使用組合鍵Ctrl+Shift+N。現(xiàn)在你可以看到4 個(gè)窗格膀捷。

如果你很重視一段代碼迈嘹,那么腳本編輯器就是存放這段代碼的絕好位置。你可以在控制臺(tái)中不斷調(diào)試,一旦代碼正常運(yùn)行并輸出預(yù)期結(jié)果秀仲,你就可以將其放在腳本編輯器中融痛。當(dāng)退出RStudio 時(shí),它會(huì)自動(dòng)保存編輯器中的內(nèi)容神僵,并在重新打開(kāi)時(shí)自動(dòng)加載編輯器中的內(nèi)容雁刷。盡管如此,我們還是應(yīng)該定時(shí)保存腳本挑豌,并做好備份安券。

4.1 運(yùn)行代碼

腳本編輯器還非常適合建立復(fù)雜的ggplot2 圖形或較長(zhǎng)的dplyr 操作序列。有效使用腳本編輯器的關(guān)鍵是記住最重要的快捷鍵之一:Ctrl+Enter氓英。這組快捷鍵會(huì)在控制臺(tái)中執(zhí)行當(dāng)前的R 語(yǔ)句侯勉。例如,輸入以下代碼后铝阐,如果光標(biāo)在█ 處址貌,那么按Ctrl+Enter 會(huì)運(yùn)行生成not_cancedlled 的完整命令,并將光標(biāo)移到下一個(gè)語(yǔ)句(即以not_cancelled %>% 開(kāi)頭的語(yǔ)句)徘键。因此练对,重復(fù)按Ctrl+Enter 就可以輕松運(yùn)行整個(gè)腳本:

除了按照語(yǔ)句順序運(yùn)行,還可以一次性運(yùn)行整個(gè)腳本:Ctrl+Shift+S吹害。定期運(yùn)行整個(gè)腳本是非常好的做法螟凭,可以讓你確認(rèn)腳本中所有重要的代碼都沒(méi)有問(wèn)題。

4.2 Rstudio自動(dòng)診斷

腳本編輯器還會(huì)利用紅色波浪線和邊欄的紅叉來(lái)高亮顯示語(yǔ)法錯(cuò)誤:

將鼠標(biāo)移到紅叉上就可以看到錯(cuò)誤提示:

RStudio 還能找出潛在的代碼問(wèn)題:

第五章:探索性數(shù)據(jù)分析

5.1 簡(jiǎn)介

本章將展示如何使用可視化方法和數(shù)據(jù)轉(zhuǎn)換來(lái)系統(tǒng)化地探索數(shù)據(jù)它呀,統(tǒng)計(jì)學(xué)家將這項(xiàng)任務(wù)稱為探索性數(shù)據(jù)分析(exploratory data analysis螺男,EDA)。EDA 是一個(gè)可迭代的循環(huán)過(guò)程纵穿,具有以下作用下隧。
(1) 對(duì)數(shù)據(jù)提出問(wèn)題。
(2) 對(duì)數(shù)據(jù)進(jìn)行可視化谓媒、轉(zhuǎn)換和建模淆院,進(jìn)而找出問(wèn)題的答案。
(3) 使用上一個(gè)步驟的結(jié)果來(lái)精煉問(wèn)題句惯,并提出新問(wèn)題土辩。
EDA 并不是具有嚴(yán)格規(guī)則的正式過(guò)程,它首先是一種思維狀態(tài)宗弯。在EDA 的初始階段脯燃,應(yīng)該天馬行空地發(fā)揮想象力,并考察和試驗(yàn)?zāi)軌蛳氲降乃蟹椒杀!S行┫敕ㄊ切械猛ǖ模行┫敕▌t會(huì)無(wú)疾而終欲主。當(dāng)探索更進(jìn)一步時(shí)邓厕,你就可以鎖定容易產(chǎn)生成果的幾個(gè)領(lǐng)域逝嚎,將最終想法整理成文,并與他人進(jìn)行溝通详恼。

EDA 是所有數(shù)據(jù)分析過(guò)程中的重要環(huán)節(jié)补君,因?yàn)榭偸切枰疾煲幌聰?shù)據(jù)質(zhì)量,即使你可以不費(fèi)吹灰之力就找出問(wèn)題昧互。數(shù)據(jù)清洗只是EDA 的一項(xiàng)具體應(yīng)用挽铁,此時(shí)你提出的問(wèn)題是,數(shù)據(jù)是否符合預(yù)期敞掘。要想進(jìn)行數(shù)據(jù)清洗叽掘,需要使用所有的EDA 工具:可視化、數(shù)據(jù)轉(zhuǎn)換和建模玖雁。

5.2 問(wèn)題

EDA 期間的目標(biāo)是獲取對(duì)數(shù)據(jù)的理解更扁。進(jìn)行EDA 的最簡(jiǎn)單的方式就是將問(wèn)題作為指導(dǎo)調(diào)查研究的工具。提出問(wèn)題后赫冬,這個(gè)問(wèn)題就使得你將注意力集中在數(shù)據(jù)集中的特定部分浓镜,并幫助你進(jìn)行有關(guān)圖形、模型和數(shù)據(jù)轉(zhuǎn)換的決定劲厌。

EDA 本質(zhì)上是一個(gè)創(chuàng)造性過(guò)程膛薛。和多數(shù)創(chuàng)造性過(guò)程一樣,問(wèn)題的質(zhì)量關(guān)鍵在于問(wèn)題的數(shù)量补鼻。分析過(guò)程的開(kāi)始階段很難提出有啟發(fā)性的問(wèn)題哄啄,因?yàn)槟悴⒉恢罃?shù)據(jù)集中包含了哪些真知灼見(jiàn)。另一方面辽幌,你提出的每個(gè)新問(wèn)題都可以揭示數(shù)據(jù)中的新內(nèi)容增淹,并增加發(fā)現(xiàn)知識(shí)的機(jī)會(huì)。如果在知識(shí)發(fā)現(xiàn)的基礎(chǔ)上不斷使用新問(wèn)題來(lái)補(bǔ)充每個(gè)老問(wèn)題乌企,那么你就可以快速地獲取數(shù)據(jù)中最令人感興趣的部分虑润,并總結(jié)出一組發(fā)人深省的問(wèn)題。

對(duì)于應(yīng)該提出什么樣的問(wèn)題來(lái)指導(dǎo)我們的研究加酵,現(xiàn)在還沒(méi)有確定的規(guī)則拳喻。但有兩類問(wèn)題總是有助于我們?cè)跀?shù)據(jù)中發(fā)現(xiàn)知識(shí)。我們可以粗略地將這兩類問(wèn)題表述如下猪腕。

(1) 變量本身會(huì)發(fā)生何種變動(dòng)冗澈?
(2) 不同變量之間會(huì)發(fā)生何種相關(guān)變動(dòng)?

本章剩余部分會(huì)繼續(xù)討論這兩個(gè)問(wèn)題陋葡。我們將解釋什么是變動(dòng)亚亲,什么是相關(guān)變動(dòng),并介紹回答這兩個(gè)問(wèn)題的幾種方法。為了簡(jiǎn)化討論捌归,我們先定義幾個(gè)術(shù)語(yǔ)肛响。

? 變量:一種可測(cè)量的數(shù)量、質(zhì)量或?qū)傩浴?br> ? 值:變量在測(cè)量時(shí)的狀態(tài)惜索。變量值在每次測(cè)量之間可以發(fā)生改變特笋。
? 觀測(cè):或稱個(gè)案,指在相同條件下進(jìn)行的一組測(cè)量(通常巾兆,一個(gè)觀測(cè)中的所有測(cè)量是在同一時(shí)間對(duì)同一對(duì)象進(jìn)行的)猎物。一個(gè)觀測(cè)會(huì)包含多個(gè)值,每個(gè)值關(guān)聯(lián)到不同的變量角塑。有時(shí)我們會(huì)將觀測(cè)稱為數(shù)據(jù)點(diǎn)蔫磨。
? 表格數(shù)據(jù):一組值的集合,其中每個(gè)值都關(guān)聯(lián)一個(gè)變量和一個(gè)觀測(cè)吉拳。如果每個(gè)值都有自己所屬的“單元”质帅,每個(gè)變量都有自己所屬的列,每個(gè)觀測(cè)都有自己所屬的行留攒,那么表格數(shù)據(jù)就是整潔的煤惩。

5.3 變動(dòng)

變動(dòng)是每次測(cè)量時(shí)數(shù)據(jù)值的變化趨勢(shì)。實(shí)際生活中很容易看到變動(dòng)炼邀。如果對(duì)任意連續(xù)型變量進(jìn)行兩次測(cè)量魄揉,那么會(huì)得到兩個(gè)不同的結(jié)果,即使測(cè)量的是一個(gè)常數(shù)(如光速)拭宁,情況也是如此洛退。每次測(cè)量的結(jié)果都包括少量誤差,誤差在每次測(cè)量間是不同的杰标。如果測(cè)量多個(gè)項(xiàng)目(如不同人的眼睛顏色)或進(jìn)行多次測(cè)量(如電池在不同時(shí)刻的電量)兵怯,分類變量也會(huì)發(fā)生變化。所有變量都有自己的變動(dòng)模式腔剂,可以揭示出一些有趣的信息媒区。理解這種模式的最好方法就是對(duì)變量值的分布進(jìn)行可視化表示。

5.3.1 對(duì)分布進(jìn)行可視化表示

對(duì)變量分布進(jìn)行可視化的方法取決于變量是分類變量還是連續(xù)變量掸犬。如果僅在較小的集合內(nèi)取值袜漩,那么這個(gè)變量就是分類變量。分類變量在R 中通常保存為因子或字符向量湾碎。要想檢查分類變量的分布只恨,可以使用條形圖:

ggplot(data = diamonds) +geom_bar(mapping = aes(x = cut))

條形的高度表示每個(gè)x 值中觀測(cè)的數(shù)量辕近,可以使用dplyr::count() 手動(dòng)計(jì)算出這些值:

> diamonds %>%
+   count(cut)
# A tibble: 5 x 2
  cut           n
  <ord>     <int>
1 Fair       1610
2 Good       4906
3 Very Good 12082
4 Premium   13791

如果可以在無(wú)限大的有序集合中任意取值翻斟,那么這個(gè)變量就是連續(xù)變量曲聂。數(shù)值型和日期時(shí)間型變量就是連續(xù)變量的兩個(gè)例子递惋。要想檢查連續(xù)變量的分布,可以使用直方圖:

ggplot(data = diamonds) +
  geom_histogram(mapping = aes(x = carat), binwidth = 0.5)

可以通過(guò)dplyr::count() 和ggplot2::cut_width() 函數(shù)的組合來(lái)手動(dòng)計(jì)算結(jié)果:

> diamonds %>%
+   count(cut_width(carat, 0.5))
# A tibble: 11 x 2
   `cut_width(carat, 0.5)`     n
   <fct>                   <int>
 1 [-0.25,0.25]              785
 2 (0.25,0.75]             29498
 3 (0.75,1.25]             15977
 4 (1.25,1.75]              5313
 5 (1.75,2.25]              2002
 6 (2.25,2.75]               322
 7 (2.75,3.25]                32
 8 (3.25,3.75]                 5
 9 (3.75,4.25]                 4
10 (4.25,4.75]                 1

直方圖對(duì)x 軸進(jìn)行等寬分箱雹顺,然后使用條形的高度來(lái)表示落入每個(gè)分箱的觀測(cè)的數(shù)量丹墨。在上圖中廊遍,最高的條形表示幾乎有30 000 個(gè)觀測(cè)的carat 值在0.25 和0.75 之間嬉愧,這兩個(gè)值分別是條形的左側(cè)值和右側(cè)值。

使用binwidth 參數(shù)來(lái)設(shè)定直方圖中的間隔的寬度喉前,該參數(shù)是用x 軸變量的單位來(lái)度量的没酣。在使用直方圖時(shí),你應(yīng)該試驗(yàn)一下不同的分箱寬度卵迂,因?yàn)椴煌姆窒鋵挾瓤梢越沂静煌哪J皆1恪@纾绻豢紤]重量小于3 克拉的鉆石见咒,并選擇一個(gè)更小的分箱寬度偿衰,那么直方圖如下所示:

smaller <- diamonds %>%
  filter(carat < 3)
ggplot(data = smaller, mapping = aes(x = carat)) +
  geom_histogram(binwidth = 0.1)

如果想要在同一張圖上疊加多個(gè)直方圖,那么我們建議你使用geom_freqploy() 函數(shù)來(lái)代替geom_histogram() 函數(shù)改览。geom_freqploy() 可以執(zhí)行和geom_histogram() 同樣的計(jì)算過(guò)程下翎,但前者不使用條形來(lái)顯示計(jì)數(shù),而是使用折線宝当。疊加的折線遠(yuǎn)比疊加的條形更容易理解:


5.3.2 典型值

條形圖和直方圖都用比較高的條形表示變量中的常見(jiàn)值视事,而用比較矮的條形表示變量中不常見(jiàn)的值。沒(méi)有條形的位置表示數(shù)據(jù)中沒(méi)有這樣的值庆揩。為了將這些信息轉(zhuǎn)換為有用的問(wèn)題俐东,看看是否具有意料之外的情況。

? 哪些值是最常見(jiàn)的订晌?為什么虏辫?
? 哪些值是非常罕見(jiàn)的?為什么锈拨?這和你的預(yù)期相符嗎砌庄?
? 你能發(fā)現(xiàn)任何異乎尋常的模式嗎?如何解釋推励?

作為示例鹤耍,可以從以下直方圖發(fā)現(xiàn)幾個(gè)有趣的問(wèn)題。
? 為什么重量為整數(shù)克拉和常見(jiàn)分?jǐn)?shù)克拉的鉆石更多验辞?
? 為什么位于每個(gè)峰值稍偏右的鉆石比稍偏左的鉆石更多稿黄?
? 為什么沒(méi)有重量超過(guò)3 克拉的鉆石?

ggplot(data = smaller, mapping = aes(x = carat)) +
  geom_histogram(binwidth = 0.01)

一般來(lái)說(shuō)跌造,相似值聚集形成的簇表示數(shù)據(jù)中存在子組杆怕。為了理解子組族购,我們提出以下問(wèn)題。
? 每個(gè)簇中的觀測(cè)是如何相似的陵珍?
? 不同簇之間的觀測(cè)是如何不相似的寝杖?
? 如何解釋或描述各個(gè)簇?
? 為什么有些簇的外觀可能具有誤導(dǎo)作用互纯?
以下的直方圖顯示了美國(guó)黃石國(guó)家公園中的老忠實(shí)噴泉的272 次噴發(fā)的時(shí)長(zhǎng)(單位為分鐘)瑟幕。噴發(fā)時(shí)間似乎聚集成了兩組:短噴發(fā)(2 分鐘左右)和長(zhǎng)噴發(fā)(4~5 分鐘),這兩組間幾乎沒(méi)有其他噴發(fā)時(shí)間:

ggplot(data = faithful, mapping = aes(x = eruptions)) +
  geom_histogram(binwidth = 0.25)

5.3.3 異常值

異常值是與眾不同的觀測(cè)或者是模式之外的數(shù)據(jù)點(diǎn)留潦。有時(shí)異常值是由于數(shù)據(jù)錄入錯(cuò)誤而產(chǎn)生的只盹;有時(shí)異常值則能開(kāi)辟出一塊重要的新科學(xué)領(lǐng)域。如果數(shù)據(jù)量比較大兔院,有時(shí)很難在直方圖上發(fā)現(xiàn)異常值殖卑。例如,查看鉆石數(shù)據(jù)集中y 軸變量的分布坊萝,唯一能表示存在異常值的證據(jù)是孵稽,y 軸的取值范圍出奇得寬:

ggplot(diamonds) +
  geom_histogram(mapping = aes(x = y), binwidth = 0.5)

正常值分箱中的觀測(cè)太多了,以致于包括異常值的分箱高度太低十偶,因此我們根本看不見(jiàn)(如果仔細(xì)觀察x 軸0 刻度附近菩鲜,沒(méi)準(zhǔn)你能發(fā)現(xiàn)點(diǎn)什么)。為了更容易發(fā)現(xiàn)異常值扯键,我們可以使用coord_cartesian() 函數(shù)將y 軸靠近0 的部分放大:

ggplot(diamonds) +
geom_histogram(mapping = aes(x = y), binwidth = 0.5) +
coord_cartesian(ylim = c(0, 50))

coord_cartesian() 函數(shù)中有一個(gè)用于放大x 軸的xlim() 參數(shù)睦袖。ggplot2 中也有功能稍有區(qū)別的xlim() 和ylim() 函數(shù):它們會(huì)忽略溢出坐標(biāo)軸范圍的那些數(shù)據(jù)。

這樣一來(lái)荣刑,我們就可以看出有3 個(gè)異常值馅笙,分別位于0、30 左右和60 左右厉亏。我們使用
dplyr 將它們找出來(lái):

> unusual <- diamonds %>%
+   filter(y < 3 | y > 20) %>%
+   arrange(y)
> unusual
# A tibble: 9 x 10
  carat cut   color clarity depth table price     x     y
  <dbl> <ord> <ord> <ord>   <dbl> <dbl> <int> <dbl> <dbl>
1  1    Very~ H     VS2      63.3    53  5139  0      0  
2  1.14 Fair  G     VS1      57.5    67  6381  0      0  
3  1.56 Ideal G     VS2      62.2    54 12800  0      0  
4  1.2  Prem~ D     VVS1     62.1    59 15686  0      0  
5  2.25 Prem~ H     SI2      62.8    59 18034  0      0  
6  0.71 Good  F     SI2      64.1    60  2130  0      0  
7  0.71 Good  F     SI2      64.1    60  2130  0      0  
8  0.51 Ideal E     VS1      61.8    55  2075  5.15  31.8
9  2    Prem~ H     SI2      58.9    57 12210  8.09  58.9
# ... with 1 more variable: z <dbl>

y 變量測(cè)量鉆石的三個(gè)維度之一董习,單位為毫米。我們知道鉆石的寬度不可能是0 毫米爱只,因此這些值肯定是錯(cuò)誤的皿淋。我們也完全可以認(rèn)為32 毫米和59 毫米同樣是令人難以置信的,這樣的鉆石長(zhǎng)度超過(guò)1 英寸(1 英寸=2.54 厘米)恬试,簡(jiǎn)直就是無(wú)價(jià)之寶窝趣!

5.4缺失值

如果在數(shù)據(jù)集中發(fā)現(xiàn)異常值,但只想繼續(xù)進(jìn)行其余的分析工作训柴,那么有2 種選擇哑舒。

? 將帶有可疑值的行全部丟棄

diamonds2 <- diamonds %>%
  filter(between(y, 3, 20))

不建議使用這種方式,因?yàn)橐粋€(gè)無(wú)效測(cè)量不代表所有測(cè)量都是無(wú)效的幻馁。此外洗鸵,如果數(shù)據(jù)質(zhì)量不高越锈,若對(duì)每個(gè)變量都采取這種做法,那么你最后可能會(huì)發(fā)現(xiàn)數(shù)據(jù)已經(jīng)所剩無(wú)幾膘滨!

? 相反甘凭,我們建議使用缺失值來(lái)代替異常值。最簡(jiǎn)單的做法就是使用mutate() 函數(shù)創(chuàng)建一個(gè)新變量來(lái)代替原來(lái)的變量火邓。你可以使用ifelse() 函數(shù)將異常值替換為NA:

diamonds2 <- diamonds %>%
  mutate(y = ifelse(y < 3 | y > 20, NA, y))

ifelse() 函數(shù)有3 個(gè)參數(shù)丹弱。第一個(gè)參數(shù)test 應(yīng)該是一個(gè)邏輯向量,如果test 為T(mén)RUE贡翘,函數(shù)結(jié)果就是第二個(gè)參數(shù)yes 的值蹈矮;如果test 為FALSE,函數(shù)結(jié)果就是第三個(gè)參數(shù)no 的值鸣驱。
和R 一樣,ggplot2 也遵循不能無(wú)視缺失值的原則蝠咆。因?yàn)闊o(wú)法明確地繪制出缺失值踊东,所以ggplot2 在繪圖時(shí)會(huì)忽略缺失值,但會(huì)提出警告以通知缺失值被丟棄了:

> ggplot(data = diamonds2, mapping = aes(x = x, y = y)) +
+   geom_point()
Warning message:
Removed 9 rows containing missing values (geom_point).

要想不顯示這條警告刚操,可以設(shè)置na.rm = TRUE:

ggplot(data = diamonds2, mapping = aes(x = x, y = y)) +
  geom_point(na.rm = TRUE)

5.5 相關(guān)變動(dòng)

如果變動(dòng)描述的是一個(gè)變量?jī)?nèi)部的行為闸翅,那么相關(guān)變動(dòng)描述的就是多個(gè)變量之間的行為。相關(guān)變動(dòng)是兩個(gè)或多個(gè)變量以相關(guān)的方式共同變化所表現(xiàn)出的趨勢(shì)菊霜。查看相關(guān)變動(dòng)的最好方式是將兩個(gè)或多個(gè)變量間的關(guān)系以可視化的方式表現(xiàn)出來(lái)坚冀。如何進(jìn)行這種可視化表示同樣取決于相關(guān)變量的類型。

5.5.1 分類變量與連續(xù)變量

我們經(jīng)常需要探索連續(xù)變量的分布鉴逞,這種分布按照一個(gè)分類變量的值可以分為幾個(gè)組记某,就像前面的頻率多邊形圖一樣。geom_freqpoly() 的默認(rèn)外觀不太適合這種比較构捡,因?yàn)楦叨仁怯捎?jì)數(shù)給出的液南。這就意味著,如果一組觀測(cè)的數(shù)量明顯少于其他組的話勾徽,就很難看出形狀上的差別滑凉。舉個(gè)例子,我們探索一下鉆石價(jià)格是如何隨著質(zhì)量而變化的:

ggplot(data = diamonds, mapping = aes(x = price)) +
geom_freqpoly(mapping = aes(color = cut), binwidth = 500)

很難看出分布上的差別喘帚,因?yàn)榭傮w看來(lái)各組數(shù)量的差別太大了:

按分類變量的分組顯示連續(xù)變量分布的另一種方式是使用箱線圖畅姊。箱線圖是對(duì)變量值分布的一種簡(jiǎn)單可視化表示,這種圖在統(tǒng)計(jì)學(xué)家中非常流行吹由。每張箱線圖都包括以下內(nèi)容若未。

? 一個(gè)長(zhǎng)方形箱子,下面的邊表示分布的第25 個(gè)百分位數(shù)溉知,上面的邊表示分布的第75 個(gè)
百分位數(shù)陨瘩,上下兩邊的距離稱為四分位距腕够。箱子的中部有一條橫線,表示分布的中位數(shù)舌劳,
也就是分布的第50 個(gè)百分位數(shù)帚湘。這三條線可以表示分布的分散情況,還可以幫助我們
明確數(shù)據(jù)是關(guān)于中位數(shù)對(duì)稱的甚淡,還是偏向某一側(cè)大诸。
? 圓點(diǎn)表示落在箱子上下兩邊1.5 倍四分位距外的觀測(cè),這些離群點(diǎn)就是異常值贯卦,因此需
要單獨(dú)繪出资柔。
? 從箱子上下兩邊延伸出的直線(或稱為須)可以到達(dá)分布中最遠(yuǎn)的非離群點(diǎn)處。

使用geom_boxplot() 函數(shù)查看按切割質(zhì)量分類的價(jià)格分布:

ggplot(data = diamonds, mapping = aes(x = cut, y = price)) +
geom_boxplot()

雖然看不出太多關(guān)于分布的信息撵割,但箱線圖更加緊湊贿堰,因此可以更容易地比較多個(gè)類別(也更適合使用一張圖來(lái)表示)。與前面的圖形一樣啡彬,我們可以從箱線圖中發(fā)現(xiàn)違反直覺(jué)的現(xiàn)象:質(zhì)量更好的鉆石的平均價(jià)格更低羹与!你將在練習(xí)中接受這一挑戰(zhàn),說(shuō)明為什么會(huì)這樣庶灿。

cut 是一個(gè)有序因子:“一般”不如“較好”纵搁、“較好”不如“很好”,以此類推往踢。因?yàn)楹芏喾诸愖兞坎](méi)有這種內(nèi)在的順序腾誉,所以有時(shí)需要對(duì)其重新排序來(lái)繪制信息更豐富的圖形。重新排序的其中一種方法是使用reorder() 函數(shù)峻呕。
例如利职,我們看一下mpg 數(shù)據(jù)集中的class 變量。你可能很想知道公路里程因汽車類別的不同會(huì)有怎樣的變化:

ggplot(data = mpg, mapping = aes(x = class, y = hwy)) +
  geom_boxplot()

為了更容易發(fā)現(xiàn)趨勢(shì)山上,可以基于hwy 值的中位數(shù)對(duì)class 進(jìn)行重新排序:

ggplot(data = mpg, mapping = aes(
  x = reorder(class,hwy,FUN = median), 
  y = hwy)) +
  geom_boxplot()

如果變量名很長(zhǎng)眼耀,那么將圖形旋轉(zhuǎn)90 度效果會(huì)更好一些。你可以通過(guò)coord_flip() 函數(shù)完成這一操作:

5.5.2 兩個(gè)分類變量

要想對(duì)兩個(gè)分類變量間的相關(guān)變動(dòng)進(jìn)行可視化表示佩憾,需要計(jì)算出每個(gè)變量組合中的觀測(cè)數(shù)量哮伟。完成這個(gè)任務(wù)的其中一種方法是使用內(nèi)置的geom_count() 函數(shù):

ggplot(data = diamonds) +
  geom_count(mapping = aes(x = cut, y = color))

圖中每個(gè)圓點(diǎn)的大小表示每個(gè)變量組合中的觀測(cè)數(shù)量。相關(guān)變動(dòng)就表示為特定x 軸變量值與特定y 軸變量值之間的強(qiáng)相關(guān)關(guān)系妄帘。

計(jì)算變量組合中的觀測(cè)數(shù)量的另一種方法是使用dplyr:

> diamonds %>%
+   count(color, cut)
# A tibble: 35 x 3
   color cut           n
   <ord> <ord>     <int>
 1 D     Fair        163
 2 D     Good        662
 3 D     Very Good  1513
 4 D     Premium    1603
 5 D     Ideal      2834
 6 E     Fair        224
 7 E     Good        933
 8 E     Very Good  2400
 9 E     Premium    2337
10 E     Ideal      3903
# ... with 25 more rows

接著使用geom_tile() 函數(shù)和填充圖形屬性進(jìn)行可視化表示:

diamonds %>%
  count(color, cut) %>%
  ggplot(mapping = aes(x = color, y = cut)) +
  geom_tile(mapping = aes(fill = n))

如果分類變量是無(wú)序的楞黄,那么可以使用seriation 包對(duì)行和列同時(shí)進(jìn)行重新排序,以便更清楚地表示出有趣的模式抡驼。對(duì)于更大的圖形鬼廓,你可以使用d3heatmap 或heatmaply 包,這兩個(gè)包都可以生成有交互功能的圖形致盟。

5.5.3 兩個(gè)連續(xù)變量

對(duì)于兩個(gè)連續(xù)變量間的相關(guān)變動(dòng)的可視化表示碎税,我們已經(jīng)介紹了一種非常好的方法:使用geom_point() 畫(huà)出散點(diǎn)圖尤慰。你可以將相關(guān)變動(dòng)看作點(diǎn)的模式。例如雷蹂,你可以看到鉆石的克拉數(shù)和價(jià)值之間存在一種指數(shù)關(guān)系:

ggplot(data = diamonds) +
  geom_point(mapping = aes(x = carat, y = price))

隨著數(shù)據(jù)集規(guī)模的不斷增加伟端,散點(diǎn)圖的用處越來(lái)越小,因?yàn)閿?shù)據(jù)點(diǎn)開(kāi)始出現(xiàn)過(guò)繪制匪煌,并堆積在一片黑色區(qū)域中(如上面的散點(diǎn)圖所示)责蝠。我們已經(jīng)介紹了解決這個(gè)問(wèn)題的一種方法,即使用alpha 圖形屬性添加透度:

ggplot(data = diamonds) +
  geom_point(
    mapping = aes(x = carat, y = price),
    alpha = 1 / 100
  )

但是很難對(duì)特別大的數(shù)據(jù)集使用透明度萎庭。另一種解決方法是使用分箱霜医。我們之前使用了geom_histogram() 和geom_freqpoly() 函數(shù)在一個(gè)維度上進(jìn)行分箱,現(xiàn)在學(xué)習(xí)如何使用geom_bin2d() 和geom_hex() 函數(shù)在兩個(gè)維度上進(jìn)行分箱驳规。

geom_bin2d() 和geom_hex() 函數(shù)將坐標(biāo)平面分為二維分箱肴敛,并使用一種填充顏色表示落入每個(gè)分箱的數(shù)據(jù)點(diǎn)。geom_bin2d() 創(chuàng)建長(zhǎng)方形分箱达舒。geom_hex() 創(chuàng)建六邊形分箱值朋。要想使用geom_hex(),需要安裝hexbin 包:

ggplot(data = smaller) +
  geom_bin2d(mapping = aes(x = carat, y = price))
ggplot(data = smaller) +
  geom_hex(mapping = aes(x = carat, y = price))

另一種方式是對(duì)一個(gè)連續(xù)變量進(jìn)行分箱巩搏,因此這個(gè)連續(xù)變量的作用就相當(dāng)于分類變量。接下來(lái)就可以使用前面學(xué)過(guò)的對(duì)分類變量和連續(xù)變量的組合進(jìn)行可視化的技術(shù)了趾代。例如贯底,你可以對(duì)carat 進(jìn)行分箱,然后為每個(gè)組生成一個(gè)箱線圖:

ggplot(data = smaller, mapping = aes(x = carat, y = price)) +
  geom_boxplot(mapping = aes(group = cut_width(carat, 0.1)))

以上示例使用了cut_width(x, width) 函數(shù)將x 變量分成寬度為width 的分箱撒强。默認(rèn)情況下禽捆,不管其中有多少個(gè)觀測(cè),箱線圖看上去都差不多(除了離群點(diǎn)的數(shù)量不同)飘哨,因此很難分辨出每個(gè)箱線圖是對(duì)不同數(shù)量的觀測(cè)進(jìn)行摘要統(tǒng)計(jì)的胚想。如果想要體現(xiàn)這種信息,可以使用參數(shù)varwidth = TRUE 讓箱線圖的寬度與觀測(cè)數(shù)量成正比芽隆。

另一種方法是近似地顯示每個(gè)分箱中的數(shù)據(jù)點(diǎn)的數(shù)量浊服,此時(shí)可以使用cut_number() 函數(shù):

ggplot(data = smaller, mapping = aes(x = carat, y = price)) +
  geom_boxplot(mapping = aes(group = cut_number(carat, 20)))

5.6 模式和模型

數(shù)據(jù)中的模式提供了關(guān)系線索。如果兩個(gè)變量之間存在系統(tǒng)性的關(guān)系胚吁,那么這種關(guān)系就會(huì)
在數(shù)據(jù)中表現(xiàn)為一種模式牙躺。如果發(fā)現(xiàn)了模式,需要問(wèn)自己以下幾個(gè)問(wèn)題腕扶。
? 這種模式的出現(xiàn)會(huì)不會(huì)是一種巧合(也就是隨機(jī)的偶然因素)孽拷?
? 應(yīng)該如何描述這種模式中隱含的關(guān)系?
? 這種模式中隱含的關(guān)系有多強(qiáng)半抱?
? 其他變量會(huì)如何影響這種關(guān)系脓恕?
? 如果對(duì)數(shù)據(jù)的獨(dú)立分組進(jìn)行檢查膜宋,這種關(guān)系會(huì)有所變化嗎?
我們就前面提到的美國(guó)黃石國(guó)家公園中老忠實(shí)噴泉的噴發(fā)時(shí)長(zhǎng)和兩次噴發(fā)之間的等待時(shí)間
做出一張散點(diǎn)圖炼幔,該圖會(huì)顯示出一個(gè)模式:較長(zhǎng)的等待時(shí)間與較長(zhǎng)的噴發(fā)時(shí)間是相關(guān)的秋茫。
圖中還顯示出兩個(gè)簇,這個(gè)我們之前就發(fā)現(xiàn)了:

ggplot(data = faithful) +
  geom_point(mapping = aes(x = eruptions, y = waiting))

模式是數(shù)據(jù)科學(xué)中最有效的工具之一江掩,因?yàn)槠淇梢越沂鞠嚓P(guān)變動(dòng)学辱。如果說(shuō)變動(dòng)會(huì)生成不確定性,那么相關(guān)變動(dòng)就是減少不確定性环形。如果兩個(gè)變量是共同變化的策泣,就可以使用一個(gè)變量的值來(lái)更好地預(yù)測(cè)另一個(gè)變量的值。如果相關(guān)變動(dòng)可以歸因于一種因果關(guān)系(一種特殊情況)抬吟,那么就可以使用一個(gè)變量的值來(lái)控制另一個(gè)變量的值萨咕。

模型是用于從數(shù)據(jù)中抽取模式的一種工具。例如火本,我們思考一下鉆石數(shù)據(jù)危队。切割質(zhì)量與價(jià)格之間的關(guān)系是很難理解的,因?yàn)榍懈钯|(zhì)量和克拉數(shù)以及克拉數(shù)和價(jià)格之間是緊密相關(guān)的钙畔。我們可以使用模型去除價(jià)格和克拉數(shù)之間的強(qiáng)關(guān)系茫陆,這樣就可以繼續(xù)研究剩余的微妙關(guān)系。以下代碼擬合了一個(gè)模型擎析,可以根據(jù)carat 預(yù)測(cè)price簿盅,并計(jì)算出殘差(預(yù)測(cè)值和實(shí)際值之間的差別)。一旦去除克拉數(shù)對(duì)價(jià)格的影響揍魂,殘差就能反映出鉆石的價(jià)格:

library(modelr)
mod <- lm(log(price) ~ log(carat), data = diamonds)
diamonds2 <- diamonds %>%
add_residuals(mod) %>%
mutate(resid = exp(resid))
ggplot(data = diamonds2) +
geom_point(mapping = aes(x = carat, y = resid))

去除克拉數(shù)和價(jià)格之間的強(qiáng)關(guān)系后桨醋,就可以看到預(yù)料中的切割質(zhì)量與價(jià)格的關(guān)系,對(duì)于同樣大小的鉆石现斋,切割質(zhì)量更好的鉆石更昂貴:

ggplot(data = diamonds2) +
geom_boxplot(mapping = aes(x = cut, y = resid))

5.7 ggplot2調(diào)用

通常情況下喜最,一個(gè)函數(shù)的前一個(gè)或前兩個(gè)參數(shù)是非常重要的,你應(yīng)該將它們牢記于心庄蹋。ggplot() 函數(shù)的前兩個(gè)參數(shù)是data 和mapping瞬内,aes() 函數(shù)的前兩個(gè)參數(shù)是x 和y。在本書(shū)剩余的部分中蔓肯,我們不再寫(xiě)出這些參數(shù)名遂鹊,這樣既可以節(jié)省輸入時(shí)間,也可以讓代碼樣板更精簡(jiǎn)蔗包,以便更容易找出兩張圖之間的不同之處秉扑。

ggplot(data = faithful, mapping = aes(x = eruptions)) +
geom_freqpoly(binwidth = 0.25)

ggplot(faithful, aes(eruptions)) +
geom_freqpoly(binwidth = 0.25)

第六章:工作流:項(xiàng)目

6.1什么是真實(shí)的

作為R 的一名新手,你可以認(rèn)為自己的R 環(huán)境(也就是環(huán)境窗格中列出的那些對(duì)象)是“真實(shí)的”。但從長(zhǎng)遠(yuǎn)來(lái)看舟陆,你最好認(rèn)為R 腳本是“真實(shí)的”误澳。可以通過(guò)R 腳本(以及數(shù)據(jù)文件)重建R 環(huán)境秦躯,但在R 環(huán)境中重建R 腳本就要困難得多忆谓!要么被迫重敲一次內(nèi)存中的代碼(伴隨著各種輸入錯(cuò)誤),要么被迫在R 歷史記錄中埋頭翻找踱承。為了培養(yǎng)良好的使用習(xí)慣倡缠,我們強(qiáng)烈建議你指示RStudio 不在兩次會(huì)話間保存工作空間。

6.2 你的分析位于哪里

R 中有個(gè)名為工作目錄的重要概念茎活。R 在這個(gè)目錄中查找你要加載的文件昙沦,也將你要保存的文件放在這個(gè)目錄中。RStudio 在控制臺(tái)上方顯示當(dāng)前工作目錄载荔。

可以通過(guò)運(yùn)行g(shù)etwd() 命令在R 代碼中輸出這個(gè)目錄:

> getwd()
[1] "C:/Users/zszpc/Documents"

作為R 語(yǔ)言新手盾饮,你可以使用自己的主目錄、文檔目錄或計(jì)算機(jī)上其他稀奇古怪的目錄作為R 的工作目錄懒熙。但既然已經(jīng)學(xué)習(xí)了本書(shū)的6 章內(nèi)容丘损,你也應(yīng)該掌握一定的知識(shí)了。從現(xiàn)在開(kāi)始工扎,你應(yīng)該逐漸學(xué)會(huì)使用目錄來(lái)組織分析項(xiàng)目徘钥,每開(kāi)始一個(gè)項(xiàng)目,就應(yīng)該將R 的工作目錄設(shè)置為與這個(gè)項(xiàng)目相關(guān)的目錄肢娘。
還可以使用R 的命令來(lái)設(shè)置工作目錄吏饿,但我們不建議使用這種方法:

setwd("/path/to/my/CoolProject")

不要使用這種操作,因?yàn)檫€有更好的方法蔬浙,可以讓你像專家一樣管理與R 相關(guān)的工作。

6.3 路徑與目錄

路徑與目錄稍微有一點(diǎn)復(fù)雜贞远,因?yàn)槁窂接? 種基本風(fēng)格:Mac/Linux 和Windows畴博。它們主要有以下3 種區(qū)別。
? 最重要的區(qū)別是如何分隔路徑中的各個(gè)部分蓝仲。Mac 和Linux 使用的是斜杠(如plots/diamonds.pdf)俱病,Windows 使用的則是反斜杠(如plots\diamonds.pdf)。R 支持任意一種類型(不管你現(xiàn)在使用的是哪種平臺(tái))袱结,但問(wèn)題是亮隙,反斜杠在R 中具有特殊意義,因此垢夹,如果想要表示路徑中的單個(gè)反斜杠溢吻,你需要輸入2 個(gè)反斜杠!這有點(diǎn)令人沮喪,因此我們建議你一直使用Linux/Mac 風(fēng)格的斜杠促王。
? 絕對(duì)路徑(即不管你的工作目錄是什么犀盟,都指向一個(gè)位置的路徑)的形式不同。在Windows 系統(tǒng)中蝇狼,絕對(duì)路徑的開(kāi)頭是驅(qū)動(dòng)器號(hào)(如C:)或兩個(gè)反斜杠(如\servername)阅畴;在Mac/Linux 系統(tǒng)中,絕對(duì)路徑的開(kāi)頭則是斜杠“/”(如/user/hadley)迅耘。千萬(wàn)不要在腳本中使用絕對(duì)路徑贱枣,因?yàn)椴焕诜窒恚簺](méi)有任何人會(huì)和你具有完全相同的目錄設(shè)置。
? 最后一個(gè)小區(qū)別是~ 指向的位置颤专。~ 是指向主目錄的一個(gè)很方便的快捷方式纽哥。Windows其實(shí)沒(méi)有主目錄的概念,因此~ 指向的是文檔目錄血公。


轉(zhuǎn)載請(qǐng)注明周小釗的博客>>R4ds3

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末昵仅,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子累魔,更是在濱河造成了極大的恐慌摔笤,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,277評(píng)論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件垦写,死亡現(xiàn)場(chǎng)離奇詭異吕世,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)梯投,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,689評(píng)論 3 393
  • 文/潘曉璐 我一進(jìn)店門(mén)命辖,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人分蓖,你說(shuō)我怎么就攤上這事尔艇。” “怎么了么鹤?”我有些...
    開(kāi)封第一講書(shū)人閱讀 163,624評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵终娃,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我蒸甜,道長(zhǎng)棠耕,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,356評(píng)論 1 293
  • 正文 為了忘掉前任柠新,我火速辦了婚禮窍荧,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘恨憎。我一直安慰自己蕊退,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,402評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著咕痛,像睡著了一般痢甘。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上茉贡,一...
    開(kāi)封第一講書(shū)人閱讀 51,292評(píng)論 1 301
  • 那天塞栅,我揣著相機(jī)與錄音,去河邊找鬼腔丧。 笑死仿便,一個(gè)胖子當(dāng)著我的面吹牛剪个,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 40,135評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼燃乍,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼崭别!你這毒婦竟也來(lái)了树酪?” 一聲冷哼從身側(cè)響起择镇,我...
    開(kāi)封第一講書(shū)人閱讀 38,992評(píng)論 0 275
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎影暴,沒(méi)想到半個(gè)月后错邦,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,429評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡型宙,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,636評(píng)論 3 334
  • 正文 我和宋清朗相戀三年撬呢,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片妆兑。...
    茶點(diǎn)故事閱讀 39,785評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡魂拦,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出搁嗓,到底是詐尸還是另有隱情芯勘,我是刑警寧澤,帶...
    沈念sama閱讀 35,492評(píng)論 5 345
  • 正文 年R本政府宣布腺逛,位于F島的核電站借尿,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏屉来。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,092評(píng)論 3 328
  • 文/蒙蒙 一狈癞、第九天 我趴在偏房一處隱蔽的房頂上張望茄靠。 院中可真熱鬧,春花似錦蝶桶、人聲如沸慨绳。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,723評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)脐雪。三九已至厌小,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間战秋,已是汗流浹背璧亚。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,858評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留脂信,地道東北人癣蟋。 一個(gè)月前我還...
    沈念sama閱讀 47,891評(píng)論 2 370
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像狰闪,于是被迫代替她去往敵國(guó)和親疯搅。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,713評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容