--- 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] ```