---
GA: UA-159972578-2
---
###### tags: `R` `Data Manipulation` `資料前處理`
# Dplyr套件介紹
閱讀 [Rpub版本](https://rpubs.com/RitaTang/dplyr_intro) (美觀+附程式執行結果)
## 前置準備
### 1. 下載Dplyr套件
`tidyverse`套件,包含了`dplyr`、`ggplot2`,與`stringr`等數據處理常用包
```{r}
library(tidyverse) # 一次進行下載與載入套件
```
### 2. 讀取資料
```{r}
# setwd("~/camp") # 設定環境目錄
df = read.csv('athlete_all.csv', stringsAsFactors = F) # 不要將字串變數轉換成類別變數
```
## Dplyr介紹
### 1. 什麼是Dplyr?
+ `%>%`運算子(Pipeline)表示法:兼顧可讀性與精簡的特性
+ 六大主要功能:
<table>
<tr>
<th>
函數
</th>
<th>
說明
</th>
</tr>
<tr>
<td>
select()
</td>
<td>
選擇變數
</td>
</tr>
<tr>
<td>
filter()
</td>
<td>
篩選出符合條件的變數
</td>
</tr>
<tr>
<td>
arrange()
</td>
<td>
依照變數排序資料
</td>
</tr>
<tr>
<td>
summarise()
</td>
<td>
聚合函數,對變數做群組運算
</td>
</tr>
<tr>
<td>
mutate()
</td>
<td>
新增變數
</td>
</tr>
<tr>
<td>
group_by()
</td>
<td>
依照類別變數分組
</td>
</tr>
</table>
- - -
### 2. Dplyr Cheatsheet


## 實戰演練
### 1. `%>%`運算子
<b>假設今天欲確認df中變數`Games`的年份,是否與變數`year`的年份相同?</b>
#### 【一般寫法】
```{r}
year = substr(df$Games, 1, 4) # 取第1到第4個字元
str(year) # 查看資料型態: chr
year = as.integer(year) # 將資料型態從字串轉換成整數
str(year) # 查看資料型態: int
identical(df$year, year) # 查看兩者年份是否相同
```
#### 【進階寫法】
```{r}
year = as.integer(substr(df$Games, 1, 4)) # 將兩步驟直接合併為一步驟
identical(df$year, year)
```
#### 【`%>%`寫法】
```{r}
df$Games %>% substr(1,4) %>% as.integer() %>% identical(df$year)
```
#### 【小結】
寫法 | 一般 | 進階 | `%>%` |
-------- | -------- | -------- | -------- |
優點| 易讀性高 | 效率高 | 易讀又高效 |
缺點| 效率差 | 不好閱讀 | 沒學過看不懂 |
- - -
### 2. select()
說明:選擇變數
#### 【基礎篇】
只看姓名、年齡、性別
```{r}
df %>% select(Name, Age, Sex) %>%
head(10) # 只看前十筆資料
```
- - -
### 3. filter()
說明:篩選條件變數
#### 【基礎篇】
找出18歲以上的女運動員
```{r}
df %>% filter(Age>=18 & Sex=='F') %>% head(5)
```
#### 【進階篇】
找出的18歲以上的女運動員的姓名、年齡與運動項目
```{r}
df %>% filter(Age>=18 & Sex=='F') %>% # 篩選出18歲以上的女運動員
select(Name, Age, Sport) %>% # 挑選想要的欄位
head(10)
```
- - -
### 4. arrange()
說明:依變數排序
#### 【基礎篇】
將資料依據最新的年份排序
```{r}
df %>% arrange(desc(year)) %>% head(3) # 預設為正序, desc代表倒序
```
#### 【進階篇】
找出不重複的18歲以上的女運動員的姓名、年齡與運動
```{r}
df %>% filter(Age>=18 & Sex=='F') %>%
select(ID, Name, Age, Sport) %>%
arrange(Age, Sport, Name) %>% # 依照年齡,運動項目,姓名排序
.[!duplicated(.$ID),] %>% # 找出不重複的人
head(10)
```
- - -
### 5. summarise()
說明:聚合運算
#### 【基礎篇】
歷年奧運最年長運動員的歲數
```{r}
df %>% summarise(MaxAge = max(Age, na.rm=T))
```
- - -
### 6. mutate()
說明:新增變數
#### 【基礎篇】
製作一個新的變數:BMI
```{r}
df %>% mutate(BMI = (Weight/(Height*0.01)^2)) %>% head(3)
```
- - -
### 7. group_by()
說明:將變數分組
#### 【基礎篇】
依照獎牌分組
```{r}
df %>% group_by(Medal)
```
觀察以上資料框,可以發現:單一使用group_by不會對資料框產生變化。
group_by是聚合函數,目的是以此分組依據去做某種動作,因此需配合其他dplyr函數一起使用。
#### 【進階篇】
2016年奧運運動員獎盃得主的最高年齡、平均年齡、性別比與BMI
```{r}
df %>% filter(year==2016) %>% # 篩選2016年的資料
group_by(Medal) %>% # 依照獎牌分類
mutate(BMI = (Weight/(Height*0.01)^2), # 新增BMI變數
Male = (Sex=='M')) %>% # 新增男性變數(True:男; False:女)
summarise(MaxAge = max(Age), # 計算最高年齡
Age = mean(Age), # 計算平均年齡
SexRatio = mean(Male), # 計算男性比
BMI = first(BMI)) %>% # 保留BMI的變數
.[c(2,3,1),] # 依照金牌>銀牌>銅牌之順序重新排列
```
## 其他常用技巧
### 1. tapply()
+ tapply(x, index, function)
+ 將x依照index分組並做function
```{r}
tapply(df$Sport, df$year, n_distinct)
```
- - -
### 2. aggregate()
+ aggregate(x, by=list(), function)
+ 將x by list的內容分組並做function
+ 與tapply相似,但可以多層次分組
```{r}
aggregate(df$Event,
list(Sport=df$Sport,
Year=df$year),
n_distinct) %>%
head(20)
```
- - -
### 3. unique()
說明:將重複的內容只取出一個代表
```{r}
unique(df$Sport)
```
- - -
### 4. left_join()
+ left_join(x, y, by=)
+ 保留x所有資料,根據by的變數,把x沒有但y有的資料合併至x資料框
```{r}
band_members
band_instruments
band_members %>% left_join(band_instruments)
```