---
disqus: ncyubrdecoinfo
---
# R 的數學運算及邏輯判斷
### 數學運算
#### 四則運算
加減乘除代表的運算符號分別為 +, -, *, /。
> 例:5 + 5
```R
> 5+5
[1] 10
```
> 例: 3-5
```R
> 3-5
[1] -2
```
> 例: 5 ** 2
```R
> 5 ** 2
[1] 25
```
下表整理 R 所支援的常見的數學運算子(arithmetic operators)
| 運算子 | 說明 | 範例 |
| ------- | ------------- | -------- |
| + | 加 | 3 + 3 |
| - | 減 | 5 - 1 |
| * | 乘 | 2 * 2 |
| / | 除 | 2 / 3 |
| ^ 或 ** | 指數 | 5 ** 2 |
| x %% y | x 除 y 的餘數 | 5 %% 3 |
| x %/% y | x 除 y 的商數 | 13 %/% 2 |
另外像是 $\pi$、對數、加總等則是使用函式的方式,例如
```R
# pi 是常數
> pi
[1] 3.141593
```
對數計算(logarithm):
```R
# 以 10 為底
> log10(10)
[1] 1
# natural log
> log(10)
[1] 2.302585
```
指數(exponential):
```R
> exp(10)
[1] 22026.47
```
加總(summation):
```R
> sum(1,3,5,7,9)
[1] 25
```
極值(maximum or minimum values),可使用 ```max()``` 及 ```min()```
來分別計算最大值及最小值:
```R
> x <- c(3, 5, 7, 1, 4, 2)
> max(x)
[1] 7
> min(x)
[1] 1
```
平均數(mean):
```R
> x <- c(3, 5, 7, 1, 4, 2)
> mean(x)
[1] 3.666666
```
標準差(standard deviation):
```R
> x <- c(3, 5, 7, 1, 4, 2)
> sd(x)
[1] 2.160246
```
開根號(square root):
```R
> sqrt(10)
[1] 3.162278
```
你可能會發現上面的例子數字都只有七個位數,這是 R 裡頭預設的顯示位數,如果你想增加顯示的位數的話,可以使用 ```option()``` 來設定,
```R
# 設定 10 位數字
> options(digits = 10)
> pi
[1] 3.141592654
# 設定 20 位數字
> options(digits = 20)
> pi
[1] 3.141592653589793116
```
#### 矩陣運算
假設 A, B 兩個為 $3 \times 3$ 的矩陣要相乘,這兩個矩陣分別是 A 與 B,要怎麼計算呢?
$$
\mathbf{A}~=~\left[
\begin{array}{ccc}
1 & 4 & 2 \\
3 & 2 & 3 \\
2 & 3 & 1
\end{array}\right]_{~3\times3},~\mathbf{B}~=~
\left[\begin{array}{ccc}
2 & 4 & 1 \\
1 & 1 & 2 \\
3 & 5 & 2
\end{array}\right]_{~3\times3}
$$
如果是矩陣的相乘,即積(dot),是 ```%*%```,而 ```*``` 則是元素之間的相乘(即 $A_{ij}\times B_{ij}$),做法如下:
```R
# 在 R 內產生矩陣的方式為 matrix(data, nrow, ncol)
# data 是這個矩陣的數值, nrow 表示有幾列, ncol 是幾欄
# 預設會從第一欄第一列依序照欄排列數字,如果要按照列排列數字,
# 則參數為 byrow=T}
> A <- matrix(c(1,3,2,4,2,3,2,3,1),3,3)
> B <- matrix(c(2,1,3,4,1,5,1,2,2),3,3)
# A dot B
> A%*%B
[,1] [,2] [,3]
[1,] 12 18 13
[2,] 17 29 13
[3,] 10 16 10
# A 乘 B (元素相乘)
> A*B
[,1] [,2] [,3]
[1,] 2 16 2
[2,] 3 2 6
[3,] 6 15 2
```
而矩陣的轉置(transpose)則是使用 ```t()```:
```R
> A <- matrix(c(1,3,2,4,2,3,2,3,1),3,3)
> A
[,1] [,2] [,3]
[1,] 1 4 2
[2,] 3 2 3
[3,] 2 3 1
# 轉置矩陣
> t(A)
[,1] [,2] [,3]
[1,] 1 3 2
[2,] 4 2 3
[3,] 2 3 1
```
以上簡單介紹數學計算,進階的數學運算語法可使用 ```?plotmath``` 查詢。
### 邏輯判斷
除了數學運算外,在 R 裡頭該如何進行邏輯判斷呢?例如 A > B 這樣的計算,該怎麼表示呢?下表為 R 中所支援的邏輯判斷
| 邏輯判斷 | 說明 |
| ------- | ----------------- |
| > | 大於 |
| < | 小於 |
| >= | 大於等於 |
| <= | 小於等於 |
| == | 相等 |
| != | 不相等 |
| !a | 不等於a |
| a \| b | a或b |
| a & b | a而且b |
邏輯判斷的結果則是真(TRUE)、偽(FALSE)及 NA (not available),例如:
```R
> 5 > 3
[1] TRUE
> 3 != 3
[1] FALSE
> 3 == 3
[1] TRUE
> 3 <= 3
[1] TRUE
```
## 練習
假設 P 為以下的數列
$$ P = c(3,5,7,1,8,9,2,1,5,4)$$
請計算下列公式的值:
$$-\sum_{i=1}^{10} P_i * ln (P_i)$$
## 作業 1
1. 請計算 314/103 與 256/538 的餘數
2. 請計算 $log_{10} 235$ 及 $ln 555$
3. 請查出標準差的公式,並用 R 計算下列數列的標準差:
$3,10,5,1,2,9,56,38,-5$
4. 請計算下7數列的總和
$28,16,21,30,1,19,20,11,5,4,$
$9,3,18,10,22,25,23,15,24,2,$
$26,8,29,17,7,13,27,6,12,14$
5. 請計算下列兩個矩陣 $A, B$ 的 (1) 乘積以及 (2) 元素之間的相乘
$$
\mathbf{A}~=~\left[
\begin{array}{ccc}
1 & 4 & 2 & 5 \\
3 & 2 & -3 & 3 \\
2 & 3 & 1 & 13 \\
8 & 0 & 1 & -3
\end{array}\right]_{~4\times4},~\mathbf{B}~=~
\left[\begin{array}{ccc}
21 & 3 & 8 & 6\\
10 & 5 & 2 & 8 \\
3 & 5 & 2 & 1 \\
4 & 9 & 0 & -5
\end{array}\right]_{~4\times4}
$$
6. 請問什麼是費布納西數列(Fibonacci sequence; $F$)? 請計算並列出 1–20 個費布納西數($F_1, F_2, F_3, \dots, F_{20}$)
7. 下表為兩個樣區的物種組成,請計算 (1) DG01 和 DG02 的 Shannon Diversity Index (2) 兩個樣區的 Jaccard Similarity Index
:::info
hint:
(1) $$- \sum_{i=1}^{n} P_i * ln(P_i)$$
其中 $P_i = n_i/N$,$n_i$ 為該物種的株數,$N$ 為所有物種總數
(2) $$J(A,B) = \frac{|A \cap B|}{|A \cup B|}$$
:::
| 樣區id | 物種 | 株數 |
|----------|------------|-------------------|
| DG01 | 印度牛膝 | 5 |
| DG01 | 大花咸豐草 | 15 |
| DG01 | 烏面馬 | 1 |
| DG01 | 短穎馬唐 | 2 |
| DG01 | 綠珊瑚 | 1 |
| DG01 | 酢漿草 | 10 |
| DG01 | 野莧菜 | 3 |
| DG01 | 銀合歡 | 20 |
| DG01 | 馬櫻丹 | 12 |
| DG01 | 龍爪茅 | 7 |
| DG01 | 龍葵 | 3 |
| DG02 | 光果黃細心 | 1 |
| DG02 | 台灣灰毛豆 | 5 |
| DG02 | 土丁桂 | 6 |
| DG02 | 大花咸豐草 | 19 |
| DG02 | 大飛揚草 | 14 |
| DG02 | 孟仁草 | 13 |
| DG02 | 毛馬齒莧 | 12 |
| DG02 | 煉莢豆 | 10 |
| DG02 | 獨行菜 | 5 |
| DG02 | 白花牽牛 | 3 |
| DG02 | 紅花黃細心 | 6 |
| DG02 | 臭濱芥 | 7 |
| DG02 | 草梧桐 | 9 |
| DG02 | 酢漿草 | 10 |
| DG02 | 雙花草 | 11 |
| DG02 | 雞觴刺 | 12 |
| DG02 | 香茹 | 1 |
| DG02 | 香附子 | 1 |
| DG02 | 鬼針 | 1 |
## 上課練習的 R script
[2017-10-19 上課練習 R Script(點選此連結可下載)](https://gist.github.com/mutolisp/8a1bf19a4b9a1bf0eb05515b4b9414f5)
```R
## 數學計算
# 餘數和商的練習
a <- 131 %% 68
b <- 131 %/% 68
# 常數:圓周率(內建)
pi
log10(2)
log(10)
log2(10)
exp(5)
# 最大最小值,使用 max, min
max(3,1,8,7,6)
min(3,1,8,7,6)
# 計算平均數,使用 3,1,8,7,6 這個數列,用 c() 儲存成
# R 的 vector 形式
vect1 <- c(3,1,8,7,6)
mean(vect1)
# 調整小數顯示位數,預設是 7 位(包含小數點以上的數值)
# 3.141592653 --> 顯示為 ---> 3.141593
# 最大值 22
options(digits = 22)
# 矩陣運算
A <- matrix(c(1,3,2,4,2,3,2,3,1),3,3)
B <- matrix(c(2,1,3,4,1,5,1,2,2),3,3)
# 相乘積
A %*% B
# 元素之間相乘
A * B
# 練習
# 方法 1
P <- c(3,5,7,1,8,9,2,1,5,4)
p1 <- P[1]*log(P[1])
p2 <- P[2]*log(P[2])
p3 <- P[3]*log(P[3])
p4 <- P[4]*log(P[4])
p5 <- P[5]*log(P[5])
p6 <- P[6]*log(P[6])
p7 <- P[7]*log(P[7])
p8 <- P[8]*log(P[8])
p9 <- P[9]*log(P[9])
p10 <- P[10]*log(P[10])
sum(p1,p2,p3,p4,p5,p6,p7,p8,p9,p10)
## 方法二,使用 data.table
## 請先在 packages 裡安裝 data.table
library(data.table)
# 將 P 數列存成 data.table 格式
P.dt <- data.table(P)
# 新增一個欄位 n,其值為 P * log(P)
P.dt[, n := P*log(P)]
# 最後再加總起來
sum(P.dt[, n])
# 邏輯判斷
3 == 5
a <- 3
b <- 5
s1 <- c(1,3,5,7,1,3,5,5,9,8)
# factor 加總是沒有意義的
sum(factor(s1))
# 把兩個向量用 cbind (column bind) 組合起來
s2 <- cbind(s1, P)
# 看 s2 的長度(length)和維度(dim=dimension)
length(s2)
dim(s2)
# 資料結構: list
container <- list(s1,s2,P)
container[['Hollyshit']] <- c('ha', 'ha')
y <- 1:10
x <- sample(50)
x.m <- matrix(x, nrow = 10)
# 篩選資料,可以使用 [] subscription (中括號)
# 來表示:A[i,j] 代表 A data.frame 中的第 i 列,第 j 欄
# A[, j] 代表第 j 欄(整欄)
# A[i, ] 代表第 j 欄(整欄)
# 練習:
# 把第一欄小於 10 的數值找出來
# 1. 先列出第一欄
x.m[, 1]
# 2. 再加上邏輯判斷,得到的結果為 True/False
x.m[, 1] < 10
# 再使用 subscription 組合起來
x.m[, 1][x.m[, 1] < 10]
```