---
# System prepended metadata

title: '**R 學習筆記**'

---

# **R 學習筆記**

在R中，字母大小寫是有差別的。
若要中斷程式，按"esc"。
## Basic

###  基本處理語法

| 符號      | 代表指令  | 
| -------- | -------- | 
|   #      | 註解      | 
| <- , =   | 指定      | 
| ==       | 等於      | 
| !        | not      | 
| &        | and      | 
| l        | or       | 
| ?        | 文件說明   | 
|%in%      |是否介於該範圍內|


### Package相關指定
``` R
#呼叫套件
library(package)   #檢視指定套件，若無安裝，則無反應
require(package)   #同上，若無安裝，則會進行安裝
```
* 若要安裝套件，有兩種方式
``` R
install.packages("name")                    #直接安裝套件
install.packages("name", repos="web-site")  #透過網頁載入套件
```
套件相關指令
```R
update.package()                  #更新套件，若無指定套件，則更新所有套件
help(package="name") / ?name      #套件說明    
help.search("name")  
help.start()                      #顯示網路相關說明
search()                          #顯示所有下載套件 
searchpaths()                     #顯示載入套件的路徑
example()                         #執行函數的範例
```

* 基本函數指令
```R
#指定資料檔，之後可直接輸入欄位名稱
attach(data) / with(data,{可選取欄位或條件})  
assign("a",1)                     #新增變數
getwd()                           #顯示目前指定路徑
dir()                             #顯示目前路徑底下的資料夾
setwd("path")                     #設定資料夾路徑
apropos("n")                      #尋找函數，可輸入部分名稱
scan()                            #讀取或輸入資料
objects() / is()                  #顯示所有物件 
attributes() / attr()             #顯示檔案屬性
rm()                              #移除物件
sink()                            #輸出結果

nrow(a)                           #計算列數
ncol(a)                           #計算行數
dim(a)                            #計算行、列數
nchar(a)                          #計算字元個數
length(a)                         #計算list長度
head(name,n=2L)                   #檢視前幾筆資料內容
tail(name,n=nL)                   #檢視後幾筆資料內容
rename(data,new_name=old_name)    #重新命名
paste(a,b,c)                      #合併字串
unique(a)                         #去重複值
diff(a)                           #相減(後-前)
scale(a)                          #標準化
identical(a,b)                    #判斷兩a,b內容是否一樣
```
### 基本運算
1. 資料屬性

| Integer  | Double   | Numeric  | Character| Logical  | 
| -------- | -------- | -------- | -------- | -------- | 
| 整數      | 小數      |實數      | 文字      | 邏輯     | 

2. 運算子

| +  | -  | *  | / | ^, ** | sqrt() | %/% | %% |
| -- | -- | -- |-- | --    | --     |--   | -- |
| 加 | 減  | 乘 | 除 | 次方  | 開根號  |商數  | 餘數 |


3. 相關運算函數

```R=
#判斷資料屬性
class()                            
is.numeric()                        #判斷是否為此屬性
is.integer()
is.character()

as.numeric()                        #指定資料屬性
as.integer()
as.character()

sign                                #判斷正/負數
abs()                               
log() / log2() / log10()            
exp()
sum() / cumsum()                    #加總 / 累積加總
prod() / cumprod()                  #相乘 / 累積相乘
mean()
round(a,digits=n)                   #四捨五入
```
|            | Character  | Numeric  | Integer |Complex | Logical |
| --         | --         | --       |--       | --     | --      |
| as.integer | X          | O        | O       | O      | O       |
| is.integer | F          | F        | T       | F      | F       |
4. %>%運算子
其屬於`magrittr`套件中的運算子，導入一種管線（pipe）的概念，
讀取程式碼的方式從左到右，讓程式碼更簡潔、語意更清楚。
```R
library(magrittr)
x <- 1:10
>#一般寫法
mean(x)
>#運用%>%運算子
x %>% mean
```


## 變數結構
### 向量 Vector

以```c()```表示，
其元素只會顯示一種資料型態，
每個型態強弱不同： char > complex > numeric > integer > logical

* 以指標/名稱檢視資料
```r=
 #example
x <- c(a=1, b=2, c=3 )

 #列出所有資訊
> x[1] 
 a
 1
 #列出元素值
> x[[1]]
 [1] 1
 #列出元素資訊
> x["a"]
 a
 1
 #列出元素值
> x[["a"]]
 [1] 1

> x[1:2]
 a b
 1 2
```
相關函數指令
```R
seq(from= , to= , by=)                     #產生序列，by可設定等差級距
rep(x, time= , each=)                      #產生重複值，each每組重複次數
sort()                                     #排序
rank()                                     #各向量元素的排序值
```
### 陣列 Array
所有陣列的元素屬性必須一致。
兩種定義方式，
```R
rbind(x,y)                                #合併row(橫)          
cbind(x,y)                                #合併column(直)
array(x,c(a,b,c))                         #多維度的向量
```
相關函數指令
```R
dim()                                    #列出維度資訊
ncol()                                   #計算column個數
nrow()                                   #計算row個數
aperm()                                  #將陣列轉置
```
### 矩陣 Matrix
二維陣列亦為矩陣，也可用```matrix()```
相關函數指令
```R
t()                                      #將矩陣轉置
%*%                                      #矩陣相乘
diag()                                   #產生對角矩陣 / 回傳矩陣對角向量
det()                                    #計算矩陣行列式值，一定要對稱的情況
slove()                                  #傳回矩證的反舉證
eigen()                                  #計算矩陣的特徵向量與特徵值
rownames()                               #修改 / 查詢row 名稱
colnames()
```
### 因子 Factor
因子像分級過後的向量
```R
#example
x <-c(1,2,3,4,3,1)
factor(x)
 [1] 1 2 3 4 3 1 
 Levels: 1 2 3 4
```
相關函數指令
```R
is.factor()                            #是否為因子
as.factor()                            #變數轉換為因子
is.ordered()                           #是否為排序過的因子
as.ordered()                           #變數轉換為排序的因子
which()                                #找出符合條件的指標
```
### 列表 List
可儲存不同型態的變數
相關函數
```R
as.list()                              #建立列表
is.list()                              #是否為列表
attributes()                           #查看所有元素名稱
```
### 資料框架 Data frame
```data.frame```中包含著column, row
每行都是相同長度的vector組成，資料型態都要一致
在宣告的過程中，盡量先定義好欄位名稱
```R
a <- 1:5
b <- c(a,b,c,d,e)
ab <- data.frame(a,b)
#表示顯示ab框架中的a欄位
ab$a
```
### 字元資料
```R
#可使用兩種表示方法
x <- "data"
x1 <- factor("data")
#計算字串長度，但不適用於factor上
nchar(x)
```
### 遺漏值
通常以```NA```跟```NULL```來表示
但```NULL```為不存在，非完成代表遺漏值，不能暫存於在`vector`

### 日期
在R中，是以1970年1月1日開始計算天數
與SAS不同(1960年1月1日)。

使用```lubridate, chron```套件可更輕易處裡日期及時間物件
```R
#天數
date <- as.Date("2012-06-06")
#秒數
date <- as.POSIXct("2012-06-06 17:22")

```


## 讀取資料
### 1.讀取CSV
最好的使用方法是`read.table`函數，也可使用`read.csv`(也是從`read.table`延伸出來)
```R
#example
theUrl <- "http://www.jaredlander.com/data/TomatoFirst.csv"
tomato <- read.table(file=theUrl,header=TRUE,sep=",")
#sep為分隔符號，\t = tab分隔，; = 分號
```
這邊要注意的是，`data.frame`預設內容以`factor`型態儲存，
可在定義時設定`stringsAsFactors = FALSE`，
來預防文字屬性變成factor屬性。
※若檔案內容有缺漏的部分，建議使用`read.csv2 / read.delim2`讀取資料

當資料量較大，則可考慮使用`readr`套件中的`read_delim`或`data.table`套件中的`fread`，會加快執行速度。(且這兩個函數也包含了`stringsAsFactors = FALSE`)
* read_delim
主要用來讀取分隔符號的文件，
此預設第一行為欄位名稱。
```R
library(readr)
theUrl <- "http://www.jaredlander.com/data/TomatoFirst.csv"
tomato <- read_delim(file=theUrl,delim=',')
```
![](https://i.imgur.com/XxquBs8.png)

* fread
```R
library(data.table)
toma3 <- fread(input=theUrl, sep=',', header=TRUE)
head(toma3)
```
![](https://i.imgur.com/fbLAXAB.png)

### 2.讀取Excel
使用`readxl`中的`read_excel`函數
```R
#先確認要使用的分頁，再建立檔案
excel_sheets('C:/Users/Biostatistics/Downloads/ExcelExample.xlsx')
win2 <- read_excel('C:/Users/Biostatistics/Downloads/ExcelExample.xlsx',sheet='Wine')
```

### 3.讀取資料庫資料
大多資料庫是透過ODBC連結，其他無特定的資料庫可使用通用套件(RODBS)
要先使用dvDriver指定驅動程式(SQLite/ODBC)，接著用dbConnect建立與資料庫連結，
在使用DBI套件再做其他分析。

### 4.從網路提取資料

#### 4-1簡易HTML表格
可使用XML套件中的`readHTMLTable`來讀取
```R
install.packages("XML")
library(rvest,XML)
theURL <- "http://www........html"
bowl <- readHTMLTable(theURL, which = 1, header = FALSE, 
        stringsAsFactors = FALSE)
```
#### 4-2過濾網頁資料
使用Hadley Wickham的rvest套件將網頁資料轉換成可用的格式。
使用`read_html`可讀取網頁，建立存有html的xml_document物件。
以`%>%`來提取內容。
△在HTML中，定義類別需要使用句點` "."`，定義ID使用井字號` "#"`
```R
library(xml2,rvest)
rib <- read_html("https://www.jaredlander.com/data/ribalta.html")
class(rib)
rib
```
![](https://i.imgur.com/dXwgqsF.png)

#### 4-3讀取json資料
JSON(JavaScript Object Notation)是普遍的格式，
其將資料儲存為純文字檔的資料格式，
最主要使用兩個套件`rjson、jsonlite`。
```R
library(jsonlite)
pizza <- fromJSON("https://www.jaredlander.com/data/PizzaFavorites.json")
pizza
```

## 基本繪圖功能
較常使用`ggplot2`套件來繪圖。
亦可使用`lattice`套件。
### 1-1基本直方圖
```R
>hist(diamonds$carat, main="Carat Histogram", xlab="Carat")
```
![](https://i.imgur.com/gRA1lwA.png)

### 1-2散佈圖
以formula形式，y ~ x
兩種方式都可以繪圖。
```R
>plot(price ~ carat, data=diamonds)
>plot(diamonds$carat, diamonds$price)
```
![](https://i.imgur.com/yB0NRy4.png)

### 1-3箱型圖
```R
>boxplot(diamonds$carat)
```
![](https://i.imgur.com/bjNqZky.png)

### 1-4 ggplot2套件
由ggplot延伸。
1-4-1 ggplot2直方圖與機率密度圖
直方圖
```R
ggplot(data = diamonds) + geom_histogram(aes(x = carat))
```
![](https://i.imgur.com/Sxv3aRZ.png)

機率密度圖
```R
ggplot(data = diamonds) + geom_density(aes(x = carat), fill = 'grey50')
```
![](https://i.imgur.com/EWFrXxC.png)

1-4-2 ggplot2散佈圖
```R
>ggplot(diamonds, aes(x = carat, y = price)) + geom_point()
>#以顏色來區分類別
>g <- ggplot(diamonds, aes(x = carat, y = price))   
>g + geom_point(aes(color = color))
```
![](https://i.imgur.com/ZA7zhvF.png)
![](https://i.imgur.com/ts5KvpW.png)
也可以繪製成多圖層，則需使用`facet_wrap `/ `facet_grid`函數。
```R
g + geom_point(aes(color = color)) + facet_wrap(~color)
g + geom_point(aes(color = color)) + facet_grid(cut ~clarity)
>#直方圖也可以成多圖層
ggplot(diamonds, aes(x = carat)) + geom_histogram() + facet_wrap(~color)
```
![](https://i.imgur.com/MpEccAf.png)
![](https://i.imgur.com/WrCNyow.png)
![](https://i.imgur.com/g0MmWag.png)

1-4-3 ggplot2箱型圖和小提琴圖
```R
ggplot(diamonds, aes(y = carat, x = 1)) + geom_boxplot()
ggplot(diamonds, aes(y = carat, x = cut)) + geom_boxplot()
```
![](https://i.imgur.com/bv5Aeet.png)
只要轉換函數，即可將箱型圖轉換成小提琴圖
```R
ggplot(diamonds, aes(y = carat, x = cut)) + geom_violin()
```
![](https://i.imgur.com/7086LPs.png)

1-4-4 ggplot2線形圖
```R
ggplot(economics, aes(x = date, y = pop)) + geom_line()
```
![](https://i.imgur.com/tbN2l38.png)

另外一個案例
```R
>library(base,lubridate)
>#建立年份和月份變數
>economics$year <- year(economics$date)
>#label = true則表示顯示月份名稱，而非數字
>economics$month <- month(economics$date, label = TRUE)
>econ2000 <- economics[which(economics$year >= 2000),]
>library(scales)
>#建立底圖
>g <- ggplot(econ2000, aes(x = month, y = pop))
>#用group來分群
>g <- g + geom_line(aes(color = factor(year), group=year))
>#格式化y軸
>g <- g + scale_color_discrete(name="year")
>g <- g + scale_y_continuous(labels=comma)
>g <- g + labs(title = 'Population Growth', x = "Month", y = "Population")
>g
```

![](https://i.imgur.com/gwQ4xk5.png)

1-4-5 主題樣式
`ggthemes`有內建很多常用的主題樣式，以下用例子呈現。
```R
>library(ggthemes)
>g2 <- ggplot(diamonds, aes(x=carat,y=price)) + geom_point(aes(color=color))
>#分成四種繪圖風格呈現
>g2 + theme_economist() + scale_colour_economist()
>g2 + theme_excel() + scale_colour_excel()
>g2 + theme_tufte()
>g2 + theme_wsj()
```
![](https://i.imgur.com/dHMpK7P.png)
![](https://i.imgur.com/gW2HjJY.png)
![](https://i.imgur.com/Q3UeY3b.png)
![](https://i.imgur.com/BGEtWOS.png)

## R函數
最簡易的例子，建立"Hello, World!"的函數
```R
>say.hello <- function(){
    print("Hello, World!")
}
```
* 函數的引數
會使用`sprintf`函數，類似SAS中macro的概念。
```R
>sprintf("Hello %s", "Jared")
```
![](https://i.imgur.com/AMS6nV2.png)
建立字串，以輸入引數的方式呈現
```R
hello.person <- function(name){
    print(sprintf("Hello %s", name))
}
hello.person('Jared')
```
![](https://i.imgur.com/BCmhRch.png)
* 預設引數值
預設值可以是任何有效物件，例如NULL、字元、數值等。
```R
hello.person2 <- function(first, last="Doe"){
    print(sprintf("Hello %s %s", first, last))
}
hello.person2("Jared")
hello.person2("Jared","Lander")
```
![](https://i.imgur.com/wuixNyk.png)
* 附加引數
若無加上`"..."`，則會無法附加。
```R
hello.person2("Jared", extra="Goodbye")
hello.person3 <- function(first, last="Doe",...){
    print(sprintf("Hello %s %s", first, last))
}
hello.person3("Jared", extra="Goodbye")
```
![](https://i.imgur.com/aFjYrSN.png)
* 回傳的值
除了函數主體最後一個值會被輸出，也可以用`return`的方式回傳數值
例子中輸出的結果都是一樣的。
※`return`函數之後的指定不會被執行，因為函數已經被退出了。
```R
#一般函數執行
double.num <- function(x){
    x*2
}
double.num(5)
#使用return函數
double.num2 <- function(x){
    return(x*2)
}
double.num2(5)
```
* do.call
此函數允許使用者用`character`或者一個物件來指定函數名稱，所輸入的引數須以列表呈現。
```R
do.call("hello.person2",args= list(first="Jared",last="Lander"))
#亦可這樣使用
run.this <- function(x, func=mean){
    do.call(func,args = list(x))
}
run.this(1:10)
run.this(1:10,sum)
```

## 流程控制
主要控制包括`If, else, ifelse, switch`
### If else基本架構
```R
check.bool <- function(x){
    if(x == 1){
        pirnt("hello")
    } else {
        print("goodbye")
    }
}
check.bool(1)
```
### switch
如果要判斷的條件有很多個，則可使用`switch`
```R
use.switch <- function(x){
    switch(x,
           "a"="first",
           "b"="second",
           "z"="last",
           "c"="third",
           "other")
}
use.switch("g")
```
### ifelse
此函數與Excel中if的用法較相似
```R
ifelse(1 == 1, "Yes", "No")
[1] "Yes"

toTest <- c(1, 1, 0, 1, 0, 1)
ifelse(toTest == 1, "Yes", "No")
[1] "Yes" "Yes" "No" "Yes" "No" "Yes"
```
### 複合的條件檢測
若想要檢測多個物件則會使用邏輯運算子，亦即and(&, &&)和or(|, ||)
雙符號只單純比較單一個元素，
而雙符號最好用在`if`，而單符號最好用在`ifelse`。
```R
a <- c(1, 2, 0, 1)
b <- c(2, 1, 0, 1)
#可以觀察出單符號跟雙符號的差別
ifelse(a ==1 & b ==1, "Yes", "No")
[1] "No" "No" "No" "Yes"
ifelse(a ==1 && b ==1, "Yes", "No")
[1] "No"
```

## 迴圈
### for迴圈
for需要的引數可分為三個部分，
變數、in、vector (變數在vector裡面)
vector沒有限制，可以是數字或文字
```R
for(i in 1:10){
    print(i)
}
```

### while迴圈
此迴圈較少使用
```R
x <- 1
while (x <= 5) {
    print(x)
    x <- x + 1
}
```
### 迴圈的強制處理
通常會使用`next, break`
```R
#此例為跳過3，其他都會print
for (i in 1:10){
    if (i ==3){
        next
    }
    print(i)
}
#此例到4停止，print 1~3
for (i in 1:10){
    if (i ==4){
        break
    }
    print(i)
}
```

## 資料整理(data munging)
在資料分群做出一些重複性的操作，又稱為 "split-apply-combine"(拆開-套用-整合)
### Apply相關函數
`apply`函數限制性高，只能用於`matrix`，而且元素必須是同一型態。
`apply(X, MARGIN, FUN, ...)`
第一個為物件或data，第二個為=1對每一列、=2對每一行，要套用的函數 (sum, mean,...)
```R
theMatrix <- matrix(1:9, nrow=3)
apply(theMatrix, 1, sum)
[1] 12 15 18
apply(theMatrix, 2, sum)
[1]  6 15 24
```
假設矩陣中有NA值，使用sum則會變成NA，此時就要附加引數`"na.rm=TRUE"`，
就會跳過NA值繼續計算。
```R
apply(theMatrix, 1, sum)
[1] 12 NA 18
apply(theMatrix, 1, sum, na.rm = TRUE)
[1] 12 13 18
```
### lapply和sapply
`lapply`是應用於`list、vector`，輸出也以`list`呈現，
而`sapply`應用於`list、vector`，輸出也以`vector`呈現。
```R
theList <- list(A = matrix(1:9,3),B=1:5, C=matrix(1:4,2),D=2)
lapply(theList, sum)
 $A
 [1] 45
 $B
 [1] 15
 $C
 [1] 10
 $D
 [1] 2

sapply(theList, sum)
 A  B  C  D 
45 15 10  2 
```

### mapply
可以使用於多個`list`，
通常這種狀況大部分會使用迴圈，也可以使用此函數
```R
first <- list(A=matrix(1:16,4), B=matrix(1:15,5), c=1:5)
second <- list(A=matrix(1:16,4), B=matrix(1:15,3), c=15:1)
mapply(identical, first, second)
    A     B     c 
 TRUE FALSE FALSE 
 
simpleFunc <- function(x,y){
    NROW(x) + NROW(y)
}
mapply(simpleFunc, first, second)
 A  B  c 
 8  8 20 
```

### aggregate 聚合資料
可以使用此函數來達成SQL中分群(group by)再聚合(aggregation)的概念
`aggregate(formula, data, FUN, ..., subset, na.action = na.omit)`

formula為SQL group by的概念
FUN為要使用的函數
```R
>aggregate(price ~cut, diamonds, mean)
        cut    price
1      Fair 4358.758
2      Good 3928.864
3 Very Good 3981.760
4   Premium 4584.258
5     Ideal 3457.542
```
但是aggregate執行速度較慢，還有其他像是`plyr, dplyr, data.table`是比較快的。

### plyr套件
正好符合"拆開-套用-整合"的概念，
其函數主要由5個字母組成，都是ply結尾，
前兩個字母代表輸入和輸出資料的資料結構
舉幾個例子：

| 函數 | 輸入資料 | 輸出資料 |
| -------- | -------- | -------- |
| ddply    | data.frame     |data.frame     |
| llply    | list     |list    |
| ldply    | list    |data.frame     |
| aaply    | array/vector/matrix     |array/vector/matrix       |
| d_ply    | data.frame     |無(用作邊際效應)     |
* ddply
需使用`data.frame`資料屬性，
以某些變數進行分群，做各種運算，再以`data.frame`形式回傳結果。
`with()`與SAS中data的概念很像。
```R
#.variables要針對哪個變項作分群，.fun要使用甚麼函數
careerOBP <- ddply(baseball, .variables = "id", .fun = obp)
```
* llply
以`list`的形式
```R
llply(theList,sum)
laply(theList,sum)
```
* plyr輔助函數
例如`each()`可以套用多個function到函數中，但是不能使用自訂的function
```R
aggregate(price ~cut, diamonds, each(mean, median))
```
另外一個蠻好用的函數為`idata.frame`，會更快速做資料，並節省記憶體。(與`data.frame`用法相同)

### data.table
此套件是對於`data.frame`功能的延伸和強化，
```R
#data.frame與data.table的差別
theDF <- data.frame(a=1:10, b=letters[1:10], c=LETTERS[11:20],
                    d=rep(c("One", "Two", "Three"), length.out=10))
theDT <- data.table(a=1:10, b=letters[1:10], c=LETTERS[11:20],
                    d=rep(c("One", "Two", "Three"), length.out=10))
#可以注意到data.frame預設會把character轉換成factor
> class(theDF$b)
[1] "factor"
> class(theDT$b)
[1] "character"
```
而在`data.table`中，若要單看某個欄位資料，要以`list`的方式指定
```R
theDT{, list(a, c)}
```

* 索引鍵(keys)
```R
setkey(theDT,d)
```
* data.table資料分群計算
索引最主要的好處可以快速地進行資料分群計算，
雖然`aggregate`和`d*ply`函數都可做到，但`data.table`本身功能效率會比較快。
```R
>#example
#aggregate與data.table的差別
aggregate(price ~cut,diamonds,mean)
diamondsDT[, mean(price), by=cut]
diamondsDT[, list(price=mean(price)),by= cut]
```

## 使用dplyr
其用法與SQL相似
* pipe管線運算
(前面已有介紹過)
* tbl物件
其最特別的是，在檢視時預設只有一部分會顯示出來。
tbl起源於`dplyr`，後續發展成`tibble`套件，其class仍然是tbl
* select
1.可以採用巢狀的寫法，或使用pipe進行傳送
```R
select(diamonds, carat, price)
diamonds %>% select(carat, price)
diamonds %>% select(c(carat, price))
```
2.若要搜尋部分匹配(partial match)，則可使用`dplyr`中的
`starts_with, ends_with, contains`
(開頭   、      結尾    、    包含)
```R
#會顯示開頭是c的變項
diamonds %>% select(starts_with("c"))   
```
3.可利用`matches`進行正規表示法搜尋
```R
#搜尋含有r, t的變項
diamonds %>% select(matches('r.+t'))
```
* filter
可透過`filter`篩選
```R
diamonds %>% filter(cut == 'Ideal')
#可以透過%in%來篩選多個變項
diamonds %>% filter(cut %in% c('Ideal', 'Good'))
```
若篩選條件會使用到某個變數的值，則需使用`filter_()`
當需要比較複雜的條件時，則建議使用`sprintf()`來組合運算式
```R
diamonds %>% filter_(sprintf("%s == '%s'", theCol, theCut))
```
* slice
以選取特定的橫列，其需以`vector`的型態
```R
diamonds %>% slice(1:5)
```
* mutate
以新增或修改直行
```R
>diamonds %>% mutate(price/carat)
```
若要儲存篩選運算結果，則可使用`magrittr`套件中的%<>%(pipe)
```R
#此時%<>% 與 <- 意義相同
diamonds2 %<>% select(carat, price) %>% mutate(Ratio= price/carat, Double=Ratio*2)

diamonds2 <- select(carat, price) %>% mutate(Ratio= price/carat, Double=Ratio*2)
```
* summarize
可直接使用於`data.frame`中，類似`with`函數
只會回傳單一數據結果
```R
summarize(diamonds, mean(price))
# A tibble: 1 x 1
  `mean(price)`
          <dbl>
1         3933.
```
* group_by
將資料分群，與SQL概念相似
此作法會比`aggregate`更快速
```R
>diamonds %>% group_by(cut) %>% summarize(AvgPrice= mean(price))
```
* arrange
用來排序，比`order, sort`函數更容易理解
* do
用於一般性的運算上，可任意套用函數
* dplyr用於資料庫
```R
download.file("http://www.jaredlander.com/data/diamonds.db",
              destfile="C:/Users/Biostatistics/Desktop/Udemy_R_lesson/diamonds.db",mode='wb')
diaDBSource <- src_sqlite("C:/Users/Biostatistics/Desktop/Udemy_R_lesson/diamonds.db")
install.packages("dbplyr")
diaDBSource2 <- DBI::dbConnect(RSQLite::SQLite(), "C:/Users/Biostatistics/Desktop/Udemy_R_lesson/diamonds.db")
diaDBSource
diaDBSource2
diaTab <- tbl(diaDBSource, "diamonds")
diaTab
```

## purrr迭代
主要用於`list`型態，也可用於`vector`
### map
此套件中，最基礎的函數，可獨立套用於`list`每個元素中。
```R
#兩者是一樣的概念
>lapply(theList,sum)
>theList %>% map(sum)
```
### 指定map回傳的資料類型

| 函數 | 輸出型態 | 
| -------- | -------- |
| map     | list     | 
| map_int     | integer     | 
| map_dbl     | numeric     | 
| map_chr    | character     | 
| map_lgl    | logical     | 
| map_df    | data.frame     | 
```R
theList %>% map_chr(class)
```

## 資料整理
### cbind, rbind資料合併
前面有介紹到，`data.frame`可透過`vector`使用`cbind, rbind`來結合
### 資料連結
最常使用的函數為`merge`,` plyr`套件中的`join`和`data.table`的合併功能
* merge
by是用來指定索引鍵，但此函數速度較慢
```R
aid90s00s <- merge(x=Aid_90s, y=Aid_00s,
                   by.x=c("Country.Name","Program.Name"),
                   by.y=c("Country.Name","Program.Name"))
```
* plyr join合併data.frame
此執行速度較快，但所連結的每個列表中，索引鍵的名稱必須是一樣的
可以指定左連結、右連結、內部或外部連結

```R
aid90s00sjoin <- join(x=Aid_90s, y=Aid_00s,
                      by=c("Country.Name","Program.Name"))
```
* data.table合併
```R
#要先轉換成data.table，再進行合併，此例子為左連結
dt90 <- data.table(Aid_90s, key= c("Country.Name","Program.Name"))
dt00 <- data.table(Aid_00s, key= c("Country.Name","Program.Name"))
dt0090 <- dt90[dt00]
```
### 用reshape2套件轉置
直行轉成橫列稱為melting data，橫列轉成直行稱為casting data
* melt
```R
#id.var為保留的欄位，variable.name轉置後的欄位名稱，value.name轉置後數值的欄位名稱
melt00 <- melt(Aid_00s, id.vars = c("Country.Name","Program.Name"),
               variable.name = "Year", value.name = "Dollars")
```
* dcast
```R
#還原上個例子
cast00 <- dcast(melt00, Country.Name + Program.Name ~ Year,
                value.var = "Dollars")
```

## Tidyverse的整理資料
### 合併橫列與直行
與上節相似的函數為`bind_rows, bind_cols`
```R
>require(dplyr, tibble)
>SL <- tibble(sport= c("Hockey", "baseball", "football"), 
       league = c("NHL", "MLB", "NFL"))
>trophy <- tibble(trophy = c("Stanley Cup","Commissioner's Trophy",
           "Vince Lombardi Trophy"))
>tro1 <- bind_cols(SL, trophy)
>tro2 <- tribble(~sport, ~league, ~trophy,
         "Basketball", "NBA", "Larry O'Brien Championship Trophy",
         "Golf", "PGA", "Wanamaker Trophy")
>#使用tribble建立另一個tibble
>troies <- bind_rows(tro1, tro2)   
```
### 使用dplyr連結資料
呈上節，來使用函數來做不同型態的連結`left_join, right_join, inner_join, full_join, semi_join, anti_join`
```R
left_join(diamonds, diamonColor, by=c('color'='Color'))
```
`filter, unique`可以達到`semi_join, anti_join`的功用，
若處理資料庫時，則使用後者會是比較好的選擇。
### 轉換資料格式
`tidyr`就像`reshape2`的進階版，`gather`類似tibble的`melt`，
而`spread`就像`dcast`。
若不想轉置的欄位，可在欄位前面加負號。
```R
emotion %>% gather(key=Type, value = Measurement, Age, BMI, React, Regulate)
emoition %>% gather(key=Type, value = Measurement, -ID, -Test, -Gender)

emotion %>% spread(key=Type, value = Measurement)
```

## 字串處理
### paste 建立字串
此函數可以放入字串外，也可使用向量化的字串
```R
> paste("Hello", "Jared", "and others")
[1] "Hello Jared and others"
> paste("Hello", "Jared", "and others", sep = "/")
[1] "Hello/Jared/and others"
```
`collapse`會使用任意分隔符號來隔開每串文字，類似sep的概念
### 用sprintf建立含有變數的字串
前面有提到過
### 擷取文字
使用`stringr`套件會更容易
```R
#針對特定符號來分割文字
yearlist <- str_split(string = president$YEAR, pattern="-")
#與SAS中的substr一樣的概念
str_sub(president$PRESIDENT, start=1, end=3)
```
### 正規表示法
一種用來搜尋字串的特定語法，
因為沒辦法確定位置，只能用`str_detect`
```R
>#會搜尋出含有"John"的資料，
>#若要忽略大小寫，則要再增加ignore.case
>str_detect(string=president$PRESIDENT, pattern="John")
>str_detect(president$PRESIDENT, ignore.case("John"))
```
若擷取後，數據前後可能會有空格，則可使用`str_trim`來移除。
若要從資料中擷取任何有含特定字串的地方，則可使用`str_extract`
```R
str_extract(string=theStart, pattern="Jane")
#若要搜尋四位數的數字，\\d代表任何整數(0-9)
str_extract(string = theStart, "\\d{4}",20)
#此為搜尋出現過一次~三次
str_extract(string = theStart, "\\d{1,3}")
#^代表搜尋前端，$代表搜尋後端
str_extract(string = theStart, "^\\d{1,3}$")
#可以取代文字或數字
str_replace(string = theStart, pattern ="\\d", replacement="x" )
#代表所有數字都取代成x
str_replace_all(string = theStart, pattern ="\\d", replacement="x" )
```

## 機率分佈
### 常態分佈(Normal Distribution)
```R
>#常態分佈
rnorm(n, mean, sd)
>#常態分佈的機率密度，針對特地的數值
dnorm()
```
### 二項分佈(Binomial Distribution)
```R
rbinom(n, size, prob)
>#機率密度
dbinom(n, size, prob)
>#累積機率
pbinom(n, size, prob)
```
### 泊松分佈(Poisson Distribution)
```R
rpois(n,lambda)
```

## 基本統計分析
### 摘要統計(Summary Statistics)
```R
mean(), weighted.mean()#加權平均
var()#變異數 
quantile(x, probs= c(0.25,0.75)) #百分位數
summary() #同時包含mean, min, max, median，NA的個數也會算在內
```

### 相關係數(correlation)和共變異數(covariace)
```R
>#相關係數
cor(economics$pce, economics$psavert)
>#共變異數
coveconomics$pce, economics$psavert)
>#也可以時同計算多組相關係數
cor(economics[, c(2,4:6)])
>#繪製相關係數資料成對圖
GGally::ggpairs(economics[, c(2,4:6)])
```
![](https://i.imgur.com/lP7vqHI.png)

### 常態檢定
一般通常使用Shapiro-Wilk 常態性檢定，不用載入package即可檢定
但此函數有樣本數限制，大於5000筆數據則無法使用。
```R
shapiro.test(x)
```
因此，也有其他檢定常態的方法，
如nortest套件中有好幾種方法
```R
>#Anderson-Darling 常態性檢定
ad.test(x)  

>#Cramer-von Mises 檢定
cvm.test(x)

>#Lilliefors 檢定
lillie.test(x)

>#Pearson Chi-Squared 檢定
pearson.test(x)

>#Shapiro-Francia 檢定，樣本數>5000不可使用
sf.test(x)
```

### T檢定
#### 變項呈現常態
```R
>#單一樣本T檢定,雙尾檢定
>#alternative：less代表左尾檢定，greater代表右尾檢定
t.test(tips$tip, alternative = "two.sided", mu=2.5)

>#獨立樣本T檢定
>#檢測變異數是否相等
var.test(tips$tip)
>#var.equal=TRUE代表雙樣本T檢定，若=FALSE則進行Welch檢定
t.test(tip ~sex, data=tips, var.equal=TRUE)

>#成對樣本T檢定
t.test(father.son$fheight, father.son$sheight, paired=TRUE)

>#三組以上檢定(anova)
out <- aov(y ~ x)
summary(out)
>#事後檢定
>#1.Fisher's LSD
library(agricolae)
LSD.test(out,'x',console=TRUE)
>#2.Tukey's HSD
HSD.test(out,'x',console=TRUE)


```


#### 變項呈現非常態
```R
>#單一樣本檢定，使用wilcoxon signed rank test / signed test
wilcox.test(x, alternative, mu = 0)

>#獨立樣本檢定，使用wilcoxon rank sum test(mann-whitney u test)
wilcox.test(x, y, exact=F, correct=F)

>#成對樣本檢定，使用wilcoxon signed rank test
wilcox.test(x,y, exact=F, correct=F, paired=T)

>#三組以上檢定，使用kruskal-wallis test
kruskal.test(y ~ x, data = test)
```



### 變異數分析(ANOVA)
```R
tipANOVA <- aov(tip ~day-1, tips)
summary(tipANOVA)
```

## 線性模型
### 簡單線性回歸模型
```R
heightLM <- lm(sheight ~ fheight, data = fater.son)
summary(heightLM)
```

### 多元回歸模型
```R
housel <- lm(valuepersqft ~ units + sqft+ boro, data = housing)
summary(housel)
```
可將結果用coefplot繪製

### forest plot森林圖



## 存活分析
### IRR