---
disqus: yueswater
---
# 資料視覺化:`ggplot2` 中的幾何圖形層
{%hackmd @themes/orangeheart %}
<style>
.likecoin-button {
position: relative;
width: 100%;
max-width: 485px;
max-height: 240px;
margin: 0 auto;
}
.likecoin-button > div {
padding-top: 49.48454%;
}
.likecoin-button > iframe {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
</style>
###### tags: `R Language`
上一篇`ggplot2`的[教學](https://hackmd.io/@yueswater/ggplot2)中,我們提到了幾何圖形層的意義,在這裡我們可以簡單複習一下。所謂幾何圖形層,就是將原有的資料映射到平面或更高維的空間上,即
$$
\mathbb{R}^n \mapsto \mathbb{R}^k
$$
其中 $k$ 代表我們想要資料呈現的空間維度。本篇文章中,我們將一一介紹`ggplot2`中的幾何圖形層與使用方式。
## 長條圖(bar plot)
很多人會將長條圖與直方圖(histogram)搞混,認為他們都是長條狀的圖表,但兩者在使用目的上完全不同。就圖表的外觀上來看,長條圖的每個長條並不相連,直方圖則是連在一起的;就目的上來看,長條圖所要呈現的資料必須是不連續型資料,也就是統計上說的離散型變數(discrete variables),而直方圖則是呈現連續型資料,即連續型變數(continuous variables)。我們使用 `tidyverse` 裡面的 `mpg` 汽車油耗量資料庫。
### 車種與油耗量
首先,我們先來看一下 `mpg`資料庫中不同車種的數量。
```r
ggplot(mpg, aes(class)) +
geom_bar()
```
接著我們可以透過長條圖的方式顯示不同車種的油耗量(engine displacement)。
<a><img src='https://svgshare.com/i/nYB.svg' title='' /></a>
### 車種與車子驅動方式
不同汽車會因為使用目的之差異而有不同的驅動方式,詳情請參考[【汽車特企】驅動小知識:前驅、後驅以及四輪驅動有什麼不同?](https://autos.yahoo.com.tw/%E6%B1%BD%E8%BB%8A%E7%89%B9%E4%BC%81-%E9%A9%85%E5%8B%95%E5%B0%8F%E7%9F%A5%E8%AD%98-%E5%89%8D%E9%A9%85-%E5%BE%8C%E9%A9%85%E4%BB%A5%E5%8F%8A%E5%9B%9B%E8%BC%AA%E9%A9%85%E5%8B%95%E6%9C%89%E4%BB%80%E9%BA%BC%E4%B8%8D%E5%90%8C-152000135.html#:~:text=%E8%AA%AA%E8%B5%B7%E8%BB%8A%E8%BC%9B%E7%9A%84%E9%A9%85%E5%8B%95,%E5%88%B0%E7%9A%84%E8%BD%8E%E8%BB%8A%E4%BB%A5%E5%89%8D%E7%BD%AE)。

在 `mpg` 資料庫中,`drv` 便是紀錄這些車子的驅動方式。

其中 `4` 代表四輪驅動,`f`代表前輪驅動,`r`則是後輪驅動。可以發現到,SUV的車種最常使用四輪驅動。
## 直方圖(histogram)
誠如上述所言,直方圖係用以呈現連續資料的分布情況。在這裡我們使用 `diamond` 這個資料庫。
### 鑽石克拉數的數量
```r
ggplot(diamonds, aes(carat)) +
geom_histogram()
```

上面的直方圖呈現的是在這 54000 筆資料當中,不同克拉數的數量有多少。假設我們想要將上述的圖表用更細緻的方式呈現,我們可以在`geom_histogram()` 加上`binwidth`這個參數,用以調整長條的寬度。
```r
ggplot(diamonds, aes(carat)) +
geom_histogram(binwidth=0.01)
```

或是加上`bins`,直接設定圖表中必須呈現幾個長條。
```r
ggplot(diamonds, aes(carat)) +
geom_histogram(bins=200)
```

而連續型的資料是可以轉換成離散型的,我們可以利用`scale_x_binned()`進行轉換。
```r
ggplot(diamonds, aes(carat)) +
geom_bar() +
scale_x_binned()
```

就可以得到一個長條圖。
### 鑽石切工
在長條圖中,我們可以將長條以另一個變數進行填充,同樣地這個方法也適用在直方圖。
```r
ggplot(diamonds, aes(price, fill = cut)) +
geom_histogram(binwidth = 500)
```

### 鑽石價格
假設我們今天不想要關注數量,而是不同克拉數的價格,我們可以將`geom_histogram()`中`aes()`的`weight`改為`price`。
```r
ggplot(diamonds, aes(x=carat)) +
geom_histogram(aes(weight=price), binwidth = 0.1) +
ylab("price")
```

### 計算 `binwidth`
當然,我們可以透過各種方式計算長條的間距。我們可以利用函式進行計算,而此處的資料庫我們使用`economics_long`。假設研究者設定長條間距的計算方式為
$$
f(x) = 2 \times \frac{\text{IQR}}{\sqrt[3]{n}}
$$
則
```r
ggplot(economics_long, aes(value)) +
facet_wrap(~variable, scales = 'free_x') +
geom_histogram(binwidth = function(x) 2 * IQR(x) / (length(x)^(1/3)))
```

<!--
### 直方圖與密度圖
我們可以在直方圖上加上密度圖, -->
## 折線圖(polygen)
在統計學中,折線圖多用於呈現連續型變數的「趨勢」(trend),因此又稱為趨勢圖。這個段落我們使用`causaldata`這個套件中的資料庫,其提供了 Google 公司在 2015 年 5 月 4 日至 2015 年 8 月 31 日的收盤價格。
```r
install.packages("causaldata")
library(causaldata)
```
我們可以使用`geom_line()`加上折線圖的幾何圖形層,並利用`size`調整線條粗細。
```r
ggplot(google_stock, aes(x=Date, y=Google_Return)) +
geom_line(color="black", size=1.2) +
scale_x_date(date_breaks = "1 month", date_labels = "%b %Y")
```

注意到我們可以透過`scale_x_date`將 $x$ 軸的數字轉換為日期。
## 散佈圖(scatter plot)與趨勢線(trending line)
統計推論中有個十分重要的議題,便是迴歸分析。所謂迴歸分析,就是透過大量的資料建立模型,從而了解兩個或多個變數之間的相關性、相關方向與強度,從而提供研究者一項解釋或預測的指標。假設今天要研究兩個變數之間的關係,首先我們可以先將樣本點映射到二維空間上,這邊我們使用`mtcars`的資料庫,若欲研究汽車重量與每公里所耗的加侖數,可以透過`wt`與`mpg`這兩個變數進行分析。
```r
ggplot(mtcars, aes(wt, mpg)) +
geom_point()
```

即可得一個樣本點的散佈圖。
而透過統計與計量方法求得的模型可以在二維空間上繪製出一條線,稱為迴歸線,即
$$
y_i = \beta_0 + \beta_1 x_i, \quad i = 0,1,\cdots, n
$$
在`R`語言中,執行迴歸分析的方式很簡單,只要用`lm()`即可,前方的變數為自變項,後方的變數為依變項。
```r
res <- coef(lm(mpg~wt, data = mtcars))
res
## (Intercept) wt
## 37.285126 -5.344472
```
我們將迴歸分析的結果放置於`res`中,接著利用`geom_abline()`進行繪圖,其中`intercept`代表截距項,即是 $\beta_0$,`slope`則為迴歸線的斜率,$\beta_1$。
```r
ggplot(mtcars, aes(wt, mpg)) +
geom_point() +
geom_abline(intercept = res[1], slope = res[2])
```

<div class="likecoin-embed likecoin-button">
<div></div>
<iframe scrolling="no" frameborder="0" src="https://button.like.co/in/embed/xiaolong70701/button?referrer=hackmd.io"></iframe>
</div>