該部分學(xué)習(xí)內(nèi)容來自《R for Data Science》。
這次我們學(xué)習(xí)可視化與處理數(shù)據(jù)來系統(tǒng)地探索數(shù)據(jù)——統(tǒng)計(jì)學(xué)家稱之為探索性數(shù)據(jù)分析(exploratory data analysis),簡稱為EDA祟绊。
EDA是一個(gè)迭代的圓圈:
- 生成關(guān)于你所擁有數(shù)據(jù)的問題
- 通過對(duì)數(shù)據(jù)可視化涂臣、轉(zhuǎn)換和建模尋找答案
- 使用你學(xué)到的重定義你的問題或者生成新的問題
相比于嚴(yán)格的規(guī)則與流程戳气,EDA更像一種思考狀態(tài)怨愤。在EDA的初始階段杏瞻,你可以隨意探索跳入你腦海的任意一個(gè)想法符欠。
數(shù)據(jù)清理僅僅是EDA的一個(gè)應(yīng)用嫡霞,你詢問是否你的數(shù)據(jù)如你所期。想要進(jìn)行數(shù)據(jù)清理希柿,你將需要使用EDA所有的工具:可視化诊沪、轉(zhuǎn)換與建模。
準(zhǔn)備
這部分我們將使用dplyr與ggplot2交互地對(duì)數(shù)據(jù)提問并回答曾撤,請(qǐng)確保在學(xué)習(xí)前安裝好tidyverse
包端姚,可以順利進(jìn)行以下操作:
library(tidyverse)
## -- Attaching packages ------------------------------------------------------------------ tidyverse 1.2.1 --
## <U+221A> ggplot2 2.2.1 <U+221A> purrr 0.2.4
## <U+221A> tibble 1.4.2 <U+221A> dplyr 0.7.4
## <U+221A> tidyr 0.8.0 <U+221A> stringr 1.3.0
## <U+221A> readr 1.1.1 <U+221A> forcats 0.3.0
## -- Conflicts --------------------------------------------------------------------- tidyverse_conflicts() --
## x dplyr::filter() masks stats::filter()
## x dplyr::lag() masks stats::lag()
EDA的目標(biāo)是理解數(shù)據(jù),最容易實(shí)現(xiàn)的方式是用問題作為用具引導(dǎo)我們進(jìn)行探索挤悉。想要提出有質(zhì)量的問題首先必須提出大量問題渐裸。
提問的方式?jīng)]有準(zhǔn)則可言,但兩類基本問題的提出會(huì)對(duì)我們理解數(shù)據(jù)大有裨益:
- 在我的變量中有什么類型的變異?
- 在我的變量之間有什么共同的變異橄仆?
在正式進(jìn)行分析之前剩膘,允許我定義一些術(shù)語:
- 一個(gè)變量是一個(gè)你可以測量的數(shù)量、質(zhì)量或者屬性
- 一個(gè)值是當(dāng)你測量一個(gè)變量時(shí)它的狀態(tài)
- 一個(gè)觀測或者一個(gè)案例是相似條件下一組測量值的集合盆顾。一次觀測通常包含多個(gè)值怠褐,每個(gè)值與不同的變量相關(guān)聯(lián)。我將有時(shí)稱一個(gè)觀測為一個(gè)數(shù)據(jù)點(diǎn)
- 表格數(shù)據(jù)是值的集合您宪,每一個(gè)值都與一個(gè)變量和一個(gè)觀測相關(guān)聯(lián)
可視化分布
你如何可視化一個(gè)變量的分布取決于該變量是連續(xù)還是分類的奈懒。如果一個(gè)變量僅能取少量的幾個(gè)值,我們就說它是分類變量宪巨。在R中磷杏,分類變量常保存為因子或者是字符向量。想要檢查分類變量的分布捏卓,使用直方圖:
ggplot(data = diamonds) +
geom_bar(mapping = aes(x = cut))
直方圖的高度顯示了每一個(gè)x
值有多少個(gè)觀測极祸。你可以使用dplyr::count()
手動(dòng)進(jìn)行計(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
## 5 Ideal 21551
或者
diamonds %>%
group_by(cut) %>%
summarise(n = n())
## # A tibble: 5 x 2
## cut n
## <ord> <int>
## 1 Fair 1610
## 2 Good 4906
## 3 Very Good 12082
## 4 Premium 13791
## 5 Ideal 21551
想要檢查連續(xù)變量的分布,使用直方圖:
ggplot(data = diamonds) +
geom_histogram(mapping = aes(x=carat), binwidth = 0.5)
你也可以結(jié)合dplyr::count()
與ggplot2::cut_width()
手動(dòng)計(jì)算這個(gè):
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
## 11 (4.75,5.25] 1
直方圖將x軸劃分為相等的寬度(由bin控制)怠晴,然后使用每個(gè)條形的高度來代表落入該區(qū)域觀測的數(shù)目遥金。條形的寬度非常重要,不同的設(shè)定可能揭示出數(shù)據(jù)的內(nèi)在分布模式蒜田。
smaller <- diamonds %>%
filter(carat < 3)
ggplot(data = smaller, mapping = aes(x = carat)) + geom_histogram(binwidth = 0.1)
如果你想要在同一幅圖上畫多個(gè)直方圖稿械,我推薦你使用geom_freqpoly()
函數(shù)而不是geom_histogram()
,它們的內(nèi)部計(jì)算一致冲粤,但前者使用線形美莫。
ggplot(data = smaller, mapping = aes(x = carat, color = cut)) +
geom_freqpoly(binwidth = 0.1)
典型值
在條形圖和直方圖中,高的條形顯示了變量通常出現(xiàn)的值梯捕,而短的條形說明比較少見厢呵,而沒有條形出現(xiàn)的地方說明變量幾乎不可能會(huì)出現(xiàn)那個(gè)值。想要把這些信息轉(zhuǎn)為有用的問題傀顾,尋找不同尋常之處:
- 哪個(gè)值最常出現(xiàn)述吸?為什么?
- 哪個(gè)值很少出現(xiàn)?為什么锣笨?這符合你的預(yù)期嗎?
- 你可以看到任何異常的模式嗎?什么可以解釋它蝌矛?
作為一個(gè)示例,下面的直方圖表明一些有趣的問題:
- 為什么在整個(gè)克拉和普通的克拉中有更多的鉆石错英?
- 為什么每個(gè)峰頂右側(cè)的鉆石略多于每個(gè)峰頂左側(cè)的鉆石入撒?
- 為什么沒有鉆石大于3克拉?
ggplot(data = smaller, mapping = aes(x = carat)) +
geom_histogram(binwidth = 0.01)
通常椭岩,有相似值的集群表明你數(shù)據(jù)中存在亞組(可以分組)茅逮。想要理解亞組璃赡,提問:
- 每個(gè)集群內(nèi)的觀察結(jié)果如何相似?
- 如何在不同的集群中觀察到彼此不同的結(jié)果献雅?
- 你如何解釋或描述集群碉考?
- 為什么集群的外觀會(huì)產(chǎn)生誤導(dǎo)?
下面的直方圖顯示了黃石國家公園老忠實(shí)噴泉272次噴發(fā)的長度(以分鐘為單位)挺身。噴發(fā)時(shí)間似乎分為兩組:噴發(fā)時(shí)間短(約2分鐘)和噴發(fā)時(shí)間長(4-5分鐘)侯谁,但間隔很少。
ggplot(data = faithful, mapping = aes(x = eruptions)) +
geom_histogram(binwidth = 0.25)
上面的許多問題都會(huì)提示你探索變量之間的關(guān)系章钾,例如墙贱,查看一個(gè)變量的值是否可以解釋另一個(gè)變量的行為。 我們很快會(huì)做到贱傀。
不尋常的值
異常值是不尋常的觀察結(jié)果; 數(shù)據(jù)點(diǎn)似乎不符合模式惨撇。有時(shí)異常值是數(shù)據(jù)輸入錯(cuò)誤;其他時(shí)間異常值表明重要的新科學(xué)發(fā)現(xiàn)。 當(dāng)你有很多數(shù)據(jù)時(shí)府寒,在直方圖中有時(shí)很難看到異常值魁衙。例如,從鉆石數(shù)據(jù)集中分配y變量株搔。異常值的唯一證據(jù)是x軸上異常寬的限制剖淀。
ggplot(diamonds) +
geom_histogram(mapping = aes(x = y), binwidth = 0.5)
在常見的箱子有很多觀察結(jié)果,罕見的箱子都很短邪狞,以至于看不到它們(盡管也許如果你專注于0,你會(huì)發(fā)現(xiàn)一些東西)茅撞。 為了便于查看異常值帆卓,我們需要使用coord_cartesian()
縮放y軸的小值:
ggplot(diamonds) +
geom_histogram(mapping = aes(x = y), binwidth = 0.5) +
coord_cartesian(ylim = c(0, 50))
(coord_cartesian()
同樣也有一個(gè)xlim
參數(shù)當(dāng)你在需要縮小x軸時(shí)可以使用。ggplot2也有xlim()
與ylim()
函數(shù)米丘,但工作不太一樣:它們會(huì)扔掉所有超過該限制的所有數(shù)據(jù)剑令。)
這讓我們可以看到存在3個(gè)異常值:一個(gè)是0,一個(gè)30左右拄查,一個(gè)60左右吁津。我們使用dplyr把它們?nèi)〕觯?/p>
unusual <- diamonds %>%
filter(y < 3 | y > 20) %>%
select(price, x, y, z) %>%
arrange(y)
unusual
## # A tibble: 9 x 4
## price x y z
## <int> <dbl> <dbl> <dbl>
## 1 5139 0. 0. 0.
## 2 6381 0. 0. 0.
## 3 12800 0. 0. 0.
## 4 15686 0. 0. 0.
## 5 18034 0. 0. 0.
## 6 2130 0. 0. 0.
## 7 2130 0. 0. 0.
## 8 2075 5.15 31.8 5.12
## 9 12210 8.09 58.9 8.06
y變量測量這些鉆石的三個(gè)維度之一,單位為mm堕扶。 我們知道鉆石不能有0mm的寬度碍脏,所以這些值肯定是不正確的。 我們也可能懷疑32毫米和59毫米的尺寸是不合理的:那些鉆石長1英寸稍算,但價(jià)格沒有數(shù)十萬美元典尾!
無論是否存在異常值,重復(fù)進(jìn)行分析都是很好的做法糊探。如果他們對(duì)結(jié)果的影響最小钾埂,并且您無法弄清楚他們?yōu)槭裁磿?huì)出現(xiàn)這種情況河闰,那么將其替換為缺失值并繼續(xù)前進(jìn)是合理的。但是褥紫,如果它們對(duì)您的結(jié)果有重大影響姜性,則沒有理由不放棄它們。你需要弄清楚是什么導(dǎo)致了他們(例如數(shù)據(jù)輸入錯(cuò)誤)髓考,并且你在寫作中應(yīng)透露刪除了它們部念。
練習(xí)
- 探索鉆石中每個(gè)x,y和z變量的分布绳军。你學(xué)到什么印机?想想鉆石,以及哪個(gè)尺寸是長度门驾,寬度和深度射赛。
- 探索價(jià)格的分布。你發(fā)現(xiàn)什么不尋衬淌牵或令人驚訝?(提示:仔細(xì)考慮binwidth聂沙,并確保您嘗試各種值秆麸。)
- 0.99克拉多少顆鉆石? 1克拉多少錢及汉? 你認(rèn)為什么是差異的原因沮趣?
- 在放大直方圖時(shí)比較和對(duì)比
coord_cartesian()
與xlim()
或ylim()
。 如果您保留binwidth
未設(shè)置會(huì)發(fā)生什么坷随? 如果您嘗試縮放以便只顯示一半房铭,會(huì)發(fā)生什么情況?
# 1
# x 分布
ggplot(data = diamonds) + geom_histogram(mapping = aes(x = x), binwidth = 0.5)
ggplot(data = diamonds) + geom_histogram(mapping = aes(x = y), binwidth = 0.5)
ggplot(data = diamonds) + geom_histogram(mapping = aes(x = z), binwidth = 0.5)
# 發(fā)現(xiàn)它們的分布模式其實(shí)非常接近
# 鉆石長寬深有什么特點(diǎn)我不是很清楚温眉,只能按常理x,y,z分別對(duì)應(yīng)長寬深
# 2 探索價(jià)格分布
ggplot(data = diamonds) + geom_histogram(mapping = aes(x = price))
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.
# 基本趨勢(shì)是價(jià)格越高的數(shù)量越少缸匪,除了x軸5000前面有點(diǎn)反常
# 3
diamonds %>% filter(carat == 0.99) %>% count
## # A tibble: 1 x 1
## n
## <int>
## 1 23
diamonds %>% filter(carat == 0.99) %>% select(price, carat) %>%
ggplot(aes(x=price)) + geom_histogram()
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.
diamonds %>% filter(carat == 1) %>% select(price, carat) %>%
ggplot(aes(x=price)) + geom_histogram()
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.
# 4 我們以書中的例子做比較
ggplot(diamonds) +
geom_histogram(mapping = aes(x = y), binwidth = 0.5) +
coord_cartesian(ylim = c(0, 50))
ggplot(diamonds) +
geom_histogram(mapping = aes(x = y)) + ylim(0, 50)
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.
## Warning: Removed 3 rows containing missing values (geom_bar).
缺失值
如果你發(fā)現(xiàn)數(shù)據(jù)集中存在缺失值,想要簡便地進(jìn)行后續(xù)的分析类溢,你有兩個(gè)選項(xiàng):
- 丟掉出現(xiàn)異常值的整行
diamonds2 <- diamonds %>%
filter(between(y, 3, 20))
我并不推薦這樣操作凌蔬,因?yàn)橐粋€(gè)測量值出現(xiàn)問題并不代表所有數(shù)據(jù)都有問題。另外闯冷,如果你的數(shù)據(jù)質(zhì)量比較低砂心,可能會(huì)刪除絕大多數(shù)的數(shù)據(jù),那你還分析什么呢蛇耀?
- 相比于上述方法计贰,我推薦用缺失值替換異常值。最簡單的方式是使用
mutate()
去創(chuàng)建一個(gè)修改的版本躁倒,你可以使用ifelse()
函數(shù)將NA
替換異常值褐桌。
diamonds2 <- diamonds %>%
mutate(y = ifelse(y < 3| y >20, NA, y))
ifelse()
函數(shù)有三個(gè)參數(shù)荧嵌,第一個(gè)參數(shù)需要是邏輯向量,當(dāng)test
某個(gè)值為TRUE
時(shí)赃春,對(duì)應(yīng)結(jié)果就是第二個(gè)參數(shù)织中,反之是第三個(gè)參數(shù)。
像R刁笙,ggplot2應(yīng)用了缺失值從不該在沉默中缺失的哲學(xué)。當(dāng)你繪圖時(shí)很難發(fā)現(xiàn)缺失值磅氨,所以ggplot2會(huì)提醒你那么被移除了。
ggplot(data = diamonds2, mapping = aes(x=x, y=y))+
geom_point()
## Warning: 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)
有時(shí)候你會(huì)想什么讓觀測缺失了數(shù)值掐松,它與有記錄的值又有什么不同。例如探膊,在nycflights13::flights
數(shù)據(jù)集中,dep_time
變量的缺失值(參加使用dplyr數(shù)據(jù)處理一文)顯示了航班被取消了腌闯。所以你想比較安排起飛取消和沒取消的次數(shù):
nycflights13::flights %>%
mutate(
cancelled = is.na(dep_time),
sched_hour = sched_dep_time %/% 100,
sched_min = sched_dep_time %% 100,
sched_dep_time = sched_hour + sched_min /60
) %>%
ggplot(mapping = aes(sched_dep_time)) +
geom_freqpoly(mapping = aes(color = cancelled), binwidth = 1/4)
共變化
如果變化描述變量內(nèi)的行為,則共變化描述變量之間的行為工腋。 共變是兩個(gè)或更多變量的值以相關(guān)方式一起變化的趨勢(shì)。 發(fā)現(xiàn)共變化的最好方法是可視化兩個(gè)或更多變量之間的關(guān)系趁冈。 你怎么做,應(yīng)該再次取決于所涉及的變量的類型旺坠。
一個(gè)分類變量和連續(xù)變量
如前一個(gè)頻率多邊形一樣取刃,想要探索由分類變量細(xì)分的連續(xù)變量的分布是很常見的。geom_freqpoly()
的默認(rèn)外觀對(duì)于那種比較沒有用處崩侠,因?yàn)楦叨扔蒫ount給出改抡。這意味著如果其中一個(gè)組別比其他組別小得多雀摘,很難看出形狀上的差異。 例如清蚀,讓我們來探討鉆石的價(jià)格如何隨其質(zhì)量而變化:
ggplot(data = diamonds, mapping = aes(x = price)) +
geom_freqpoly(mapping = aes(color=cut), binwidth = 500)
It’s hard to see the difference in distribution because the overall counts differ so much:
ggplot(diamonds) +
geom_bar(mapping = aes(x = cut))
為了使比較更容易,我們需要交換y軸上顯示的內(nèi)容东揣。 我們不顯示計(jì)數(shù)嘶卧,而是顯示密度,這是標(biāo)準(zhǔn)化的計(jì)數(shù)钟鸵,以便每個(gè)頻率多邊形下的面積為1棺耍。
ggplot(data = diamonds, mapping = aes(x = price,
y = ..density..)) + geom_freqpoly(mapping = aes(color = cut), binwidth = 500)
這個(gè)結(jié)果有一些令人驚訝的地方 -看起來缸托,一般的鉆石(最低的質(zhì)量)的平均價(jià)格最高俐镐! 但也許這是因?yàn)轭l率多邊形有點(diǎn)難以解釋 - 在這個(gè)結(jié)果中有很多事情要做叼风。
顯示分類變量細(xì)分的連續(xù)變量分布的另一種方法是boxplot无宿。 boxplot是一種在統(tǒng)計(jì)學(xué)家中很受歡迎的價(jià)值分布的視覺縮寫。 每個(gè)boxplot包括:
- 一個(gè)從分布的第25個(gè)百分點(diǎn)延伸到第75個(gè)百分點(diǎn)的盒子彬碱,這個(gè)距離被稱為四分位間距(IQR)巷疼。在框的中間是顯示分布的中值(即第50百分位)的線。這三條線讓你了解分布的擴(kuò)散以及分布是否對(duì)稱于中值或偏向一側(cè)骡尽。
- 顯示觀察結(jié)果的如果點(diǎn)從盒子的任一邊緣落入IQR的1.5倍以上爆阶。 這些偏離點(diǎn)是不尋常的,因此單獨(dú)繪制故河。
- 從盒子兩端延伸出來的線(或胡須)分配到最遠(yuǎn)的非異常點(diǎn)。
讓我們使用geom_boxplot()
來看一下價(jià)格的分布:
ggplot(data = diamonds, mapping = aes(x=cut, y=price)) +
geom_boxplot()
我們看到關(guān)于分布的信息要少得多凑阶,但箱形圖更加緊湊,因此我們可以更輕松地比較它們(并且更適合于一個(gè)圖)师郑。 它支持反直覺的發(fā)現(xiàn)张遭,即更好質(zhì)量的鉆石平均價(jià)格更便宜菊卷!
許多分類變量沒有這樣的內(nèi)在順序,因此您可能需要對(duì)它們重新排序以提供更豐富的信息渴庆。一種方法是使用reorder()
函數(shù)。
例如耸弄,使用mpg
數(shù)據(jù)集中的class
變量。您可能有興趣了解不同類別汽車的公路里程如何變化:
ggplot(data = mpg, mapping = aes(x=class, y=hwy)) +
geom_boxplot()
想要使趨勢(shì)更清楚捌显,我們可以使用hwy
的中位數(shù)進(jìn)行排序:
ggplot(data = mpg) +
geom_boxplot(mapping = aes(x = reorder(class, hwy, FUN = median), y=hwy))
如果你由一個(gè)長的變量名摄闸,你反轉(zhuǎn)90度顯示的效果更佳:
ggplot(data = mpg) +
geom_boxplot(mapping = aes(x = reorder(class, hwy, FUN=median), y=hwy)) + coord_flip()
兩個(gè)分類變量
想要可視化兩個(gè)分類變量的共變化,你需要對(duì)每一種組合進(jìn)行計(jì)數(shù)品洛。一種方法是依賴內(nèi)置的geom_count()
:
ggplot(data = diamonds) +
geom_count(mapping = aes(x=cut, y=color))
圖中每個(gè)圓圈的大小顯示每個(gè)值組合處發(fā)生的觀察次數(shù)。 共變將表現(xiàn)為具體x值與具體y值之間的強(qiáng)相關(guān)性岛宦。
另外一種方法是使用dplyr計(jì)算計(jì)數(shù):
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()
和fill映射可視化:
diamonds %>%
count(color, cut) %>%
ggplot(mapping = aes(x=color, y=cut)) +
geom_tile(mapping = aes(fill = n))
如果分類變量無序,則可能需要使用seriation包同時(shí)對(duì)行和列進(jìn)行重新排序变汪,以便更清楚地顯示有趣的模式裙盾。 對(duì)于較大的地塊,你可能需要嘗試使用d3heatmap或heatmaply創(chuàng)建交互式地的圖形徘熔。
兩個(gè)連續(xù)變量
你已經(jīng)見過一種可以非常好可視化兩個(gè)連續(xù)變量的方式——用geom_point()
畫一個(gè)散點(diǎn)圖。你可以通過這些點(diǎn)來看變量共變化的模式山孔。例如你可以看到鉆石的大小與其價(jià)格有指數(shù)關(guān)系。
ggplot(data = diamonds) +
geom_point(mapping = aes(x=carat, y=price))
當(dāng)數(shù)據(jù)集越來越大時(shí)荷憋,散點(diǎn)圖會(huì)變得越來越?jīng)]有饱须,因?yàn)辄c(diǎn)會(huì)覆蓋糾纏到一塊。一種優(yōu)化的方式是使用alpha
映射來添加透明度台谊。
ggplot(data = diamonds) +
geom_point(mapping = aes(x=carat, y=price), alpha = 1 / 100)
但數(shù)據(jù)集如果太大效果也不好蓉媳。另一個(gè)辦法是使用geom_bin2d()
和geom_hex()
對(duì)二維數(shù)據(jù)分組。
這兩個(gè)函數(shù)可以從二維角度將某一塊區(qū)域坐標(biāo)的點(diǎn)劃分為一塊锅铅,使用顏色等映射進(jìn)行填充可視化。geom_bin2d()
創(chuàng)建矩形女坑,而geom_hex()
創(chuàng)建六邊形盟广。在使用geom_hex()
之前需要先安裝hexbin
包。
ggplot(data = smaller) +
geom_bin2d(mapping = aes(x = carat, y = price))
#install.packages("hexbin")
ggplot(data = smaller) +
geom_hex(mapping = aes(x = carat, y = price))
還有一種處理兩個(gè)連續(xù)變量的方式是將一個(gè)連續(xù)變量(進(jìn)行分組)作為分類變量看待叮叹,然后使用我們前面提到的可視化一個(gè)分類變量與一個(gè)連續(xù)變量的方式悼粮。例如:
ggplot(data = smaller, mapping = aes(x=carat, y=price)) +
geom_boxplot(mapping = aes(group = cut_width(carat, 0.1)))
上面使用的cut_width(x, width)
將x
根據(jù)寬度width
劃分了許多組別勺远。默認(rèn)不管有多少個(gè)觀測值箱線圖看起來都一樣(除了離群點(diǎn))磁奖,所以很難說明每個(gè)箱子匯總了多少數(shù)據(jù)點(diǎn)蜜托。我們可以將箱子的(寬度)大小和匯總觀測值的數(shù)目成比例嗓化,設(shè)置varwidth=TRUE
即可。
另外一種方式是盡量讓每個(gè)箱子觀察值都差不多隧枫,這可以通過cut_number()
實(shí)現(xiàn):
ggplot(data = smaller, mapping = aes(x=carat, y=price)) +
geom_boxplot(mapping = aes(group = cut_width(carat, 0.1)), varwidth = TRUE)
ggplot(data = smaller, mapping = aes(x = carat, y=price)) + geom_boxplot(mapping = aes(group = cut_number(carat, 20)))
模式與模型
數(shù)據(jù)的模式提供了(變量)關(guān)系線索炼列。如果兩個(gè)變量存在系統(tǒng)性的關(guān)系,它必定會(huì)在數(shù)據(jù)中顯示一定的模式承二。如果你想要找到一個(gè)模式,請(qǐng)這一問自己:
- 這個(gè)模式的出現(xiàn)是偶然嗎揩徊?
- 你怎么描述這個(gè)模式顯示的關(guān)系?
- 這個(gè)模式顯示的關(guān)系有多強(qiáng)礁凡?
- 有其他變量可能會(huì)影響這個(gè)關(guān)系嗎?
- 如果你只單獨(dú)看一小組的數(shù)據(jù),這個(gè)關(guān)系會(huì)改變嗎?
老忠實(shí)噴泉等待時(shí)間與噴發(fā)顯示了這樣一個(gè)模式:等待時(shí)間越長噴發(fā)也就越長伦籍。散點(diǎn)圖可以顯示我們上面注意到的兩個(gè)簇團(tuán):
ggplot(data = faithful) +
geom_point(mapping = aes(x = eruptions, y= waiting))
模型是從數(shù)據(jù)中抽取出模式的工具君珠。下面代碼擬合了一個(gè)鉆石大小carat
預(yù)測價(jià)格price
并計(jì)算殘差的模型策添。
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))
一旦你移除這種強(qiáng)相關(guān)關(guān)系晋涣,你會(huì)發(fā)現(xiàn)鉆石質(zhì)量越好價(jià)格越貴:
ggplot(data = diamonds2) +
geom_boxplot(mapping = aes(x = cut, y = resid))