今天繼續測試 R 語言的進階資料結構中的矩陣 (matrix). 本系列之前的測試筆記參考 :
#
R 語言安裝
#
在樹莓派上安裝 R 語言
#
R 語言學習筆記 (一) : 基本語法與向量
在 R 語言中, 矩陣 (matrix) 是二維資料物件, 具有列 (row) 與行 (column) 兩個維度; 三維以上的資料結構則稱為陣列 (array), 因此矩陣其實是陣列的一種特例, 即矩陣是二維陣列 (但二維陣列卻不是矩陣).
矩陣的元素可以是 numeric, character, logical, complex, raw 或 NA 等型態資料; 不過因為矩陣通常用在數值運算, 因此其元素資料型別最常見的是數值 (numeric) 或複數 (complex) 型態. 矩陣運算是向量化運算, 亦即元素對元素的運算.
一. 建立矩陣物件 :
建立矩陣有下列幾種方法 :
1. 呼叫 matrix() 函數 :
matrix(data=NA, nrow=1, ncol=1, byrow=FALSE, dimnames=NULL)
參數 :
data=資料向量或列表, 通常為 numeric 類型
nrow=列數
ncol=行數
byrow=逐列填入, 預設 FALSE 表示維逐行填入, 即第一行填完再填第二行
dimnames=列與行名稱字串向量組成的串列, 即 list(vrow, vcol)
其中前 3 個參數固定是 data, nrow, 與 ncol, 不須指名, 其餘則須指名. 例如 :
> matrix(1:12, 3, 4) #建立 3列 * 4 行矩陣 (預設逐行填入)
[,1] [,2] [,3] [,4]
[1,] 1 4 7 10
[2,] 2 5 8 11
[3,] 3 6 9 12
可見預設逐行填入是先走直的再走橫的. 若 byrow 設為 TRUE, 則先走橫的再走直的, 例如 :
> matrix(1:12, 3, 4, TRUE) #建立 3列 * 4 行矩陣 (指定逐列填入)
[,1] [,2] [,3] [,4]
[1,] 1 2 3 4
[2,] 5 6 7 8
[3,] 9 10 11 12
列數行數不必都指定, 只輸入列數即可, R 會自動計算行數, 例如 :
> matrix(1:12, 3) #只輸入列 (第二參數預設是列數)
[,1] [,2] [,3] [,4]
[1,] 1 4 7 10
[2,] 2 5 8 11
[3,] 3 6 9 12
> matrix(1:12, 4) #只輸入列 (第二參數預設是列數)
[,1] [,2] [,3]
[1,] 1 5 9
[2,] 2 6 10
[3,] 3 7 11
[4,] 4 8 12
若要在第二參數單獨指定行數, 則須指明為 ncol :
> matrix(1:12, ncol=4) #第二參數若非列數則須指明
[,1] [,2] [,3] [,4]
[1,] 1 4 7 10
[2,] 2 5 8 11
[3,] 3 6 9 12
若未指定列數與行數, 則因 byrow 預設為 FALSE, 會建立一個 n*1 的單行矩陣 :
> matrix(1:12) #未指定列數與行數排成單行矩陣
[,1]
[1,] 1
[2,] 2
[3,] 3
[4,] 4
[5,] 5
[6,] 6
[7,] 7
[8,] 8
[9,] 9
[10,] 10
[11,] 11
[12,] 12
如果向量元素無規則可循必須逐一輸入, 例如 :
> matrix(c(5,12,7,0,1,3,6,14,2,8,11,9),4)
[,1] [,2] [,3]
[1,] 5 1 2
[2,] 12 3 8
[3,] 7 6 11
[4,] 0 14 9
但是這樣輸入一長串資料可讀性不高, 可以用 byrow 方式輸入 :
> matrix(c(5,1,2,
+ 12,3,8,
+ 7,6,11,
+ 0,14,9),4,byrow=TRUE)
[,1] [,2] [,3]
[1,] 5 1 2
[2,] 12 3 8
[3,] 7 6 11
[4,] 0 14 9
這樣就可讀性就比較高了. 注意, 上面的三個加號 + 是按 Enter 鍵後 R 控制台自動顯示的, 表示指令尚未完全.
如果 data 參數傳入一個純量或 NA, 則 R 會套用
循環規則自動複製該單一數值填充整個矩陣 :
> matrix(0,4,3)
[,1] [,2] [,3]
[1,] 0 0 0
[2,] 0 0 0
[3,] 0 0 0
[4,] 0 0 0
> matrix(NA,4,3)
[,1] [,2] [,3]
[1,] NA NA NA
[2,] NA NA NA
[3,] NA NA NA
[4,] NA NA NA
由上可知, 輸出矩陣時會在左方與上方標示矩陣列與行索引位置, 但矩陣可用 matrix() 的最後一個參數 dimnames 來設定列名與欄名, 其值為列與行名稱字串向量組成的串列 list(vrow, vcol), 例如 :
> matrix(1:12, 4, dimnames=list(c("R1","R2","R3","R4"),c("C1","C2","C3")))
C1 C2 C3
R1 1 5 9
R2 2 6 10
R3 3 7 11
R4 4 8 12
可見索引標示已經改為列名與行名了. 除了在建立矩陣時就用 dimnames 參數設定外, 也可以在建立後呼叫 rownames() 與 colnames() 分別設定或修改列名與欄名 :
> m=matrix(1:12, 4)
> m
[,1] [,2] [,3]
[1,] 1 5 9
[2,] 2 6 10
[3,] 3 7 11
[4,] 4 8 12
> rownames(m) <- c("R1","R2","R3","R4") #設定列名
> m
[,1] [,2] [,3]
R1 1 5 9
R2 2 6 10
R3 3 7 11
R4 4 8 12
> colnames(m) <- c("C1","C2","C3") #設定行名
> m
C1 C2 C3
R1 1 5 9
R2 2 6 10
R3 3 7 11
R4 4 8 12
或者用 dimnames() 函數一次設定或修改, 例如 :
> m=matrix(1:12, 4)
> m
[,1] [,2] [,3]
[1,] 1 5 9
[2,] 2 6 10
[3,] 3 7 11
[4,] 4 8 12
> dimnames(m) <- list(c("R1","R2","R3","R4"),c("C1","C2","C3"))
> m
C1 C2 C3
R1 1 5 9
R2 2 6 10
R3 3 7 11
R4 4 8 12
> dimnames(m) #取得矩陣維度資訊與列行名稱
[[1]]
[1] "R1" "R2" "R3" "R4"
[[2]]
[1] "C1" "C2" "C3"
2. 呼叫 dim() 設定維度將向量或列表轉成矩陣 :
矩陣的因次或維度 (dimension, 即列數與行數) 可以呼叫 dim() 函數來查詢 :
> m=matrix(1:12, 3, 4)
> dim(v) #查詢矩陣因次
[1] 3 4 # 3 列 4 行
回應的兩個數分別為列與行. 函數 dim(v) 除了做 getter 外, 也可以做 setter, 將一個代表列數與行數的向量 c(nrow, ncol) 設定給 dim(v) 可將向量 v 轉成矩陣; 例如 :
> v=c(5,12,7,0,1,3,6,14,2,8,11,9)
> v
[1] 5 12 7 0 1 3 6 14 2 8 11 9
> class(v)
[1] "numeric" #數值型態的原型向量
> dim(v) #向量的維度是 NULL
NULL
> dim(v) <- c(4,3) #設定向量的維度是 4*3
> v
[,1] [,2] [,3]
[1,] 5 1 2
[2,] 12 3 8
[3,] 7 6 11
[4,] 0 14 9
> class(v) #向量設定維度後變成矩陣
[1] "matrix"
> dim(v)
[1] 4 3 #矩陣維度 4*3
但是若將向量的維度指定為一個三元素以上的維度向量, 則會變成陣列型態, 例如 :
> v=c(5,12,7,0,1,3,6,14,2,8,11,9)
> dim(v) <- c(2,3,2) #改成三個維度
> v
, , 1
[,1] [,2] [,3]
[1,] 5 7 1
[2,] 12 0 3
, , 2
[,1] [,2] [,3]
[1,] 6 2 11
[2,] 14 8 9
> class(v) # 變成 array 類型
[1] "array"
除了向量外, 列表也可以轉成矩陣, 同樣也是透過呼叫 dim() 設定列表的維度 :
> l=list(5,12,7,0,1,3,6,14,2,8,11,9)
> class(l)
[1] "list"
> dim(l)=c(4,3)
> l
[,1] [,2] [,3]
[1,] 5 1 2
[2,] 12 3 8
[3,] 7 6 11
[4,] 0 14 9
> class(l)
[1] "matrix"
3. 呼叫 rbind() 或 cbind() 將列向量或行向量組合成矩陣 :
建立矩陣的第三種方法是利用 rbind() 或 cbind() 將向量組合成矩陣, rbind() 是將向量當成矩陣的列組合起來, 故這些向量即為列向量, 例如 :
> rbind(c(1,5,9),c(2,6,10),c(3,7,11),c(4,8,12))
[,1] [,2] [,3]
[1,] 1 5 9
[2,] 2 6 10
[3,] 3 7 11
[4,] 4 8 12
也可以先建立列向量再組合, 這樣會把列向量變數名稱作為矩陣的列名稱, 例如 :
> R1 <- c(1,5,9) #先建立列向量
> R2 <- c(2,6,10)
> R3 <- c(3,7,11)
> R4 <- c(4,8,12)
> rbind(R1,R2,R3,R4)
[,1] [,2] [,3]
R1 1 5 9
R2 2 6 10
R3 3 7 11
R4 4 8 12
同樣地, 也可以用 cbind() 將行向量組成矩陣, 例如 :
> cbind(c(1,2,3,4),c(5,6,7,8),c(9,10,11,12))
[,1] [,2] [,3]
[1,] 1 5 9
[2,] 2 6 10
[3,] 3 7 11
[4,] 4 8 12
> C1 <- c(1,2,3,4) #先建立行向量
> C2 <- c(5,6,7,8)
> C3 <- c(9,10,11,12)
> cbind(C1,C2,C3)
C1 C2 C3
[1,] 1 5 9
[2,] 2 6 10
[3,] 3 7 11
[4,] 4 8 12
可見若先建立行向量再組合會把行向量變數名稱作為矩陣的行名稱.
4. 使用 diag() 建立對角矩陣 :
diag(x = 1, nrow=1, ncol)
參數如下 :
x=向量或矩陣
nrow=列數
ncol=行數
若 nrow=ncol 或只指定 nrow, 則 diag() 將建立一個以 x 為軸的對稱矩陣, 例如 :
> diag(1, nrow=5) #ncol 不指定時等於 nrow
[,1] [,2] [,3] [,4] [,5]
[1,] 1 0 0 0 0
[2,] 0 1 0 0 0
[3,] 0 0 1 0 0
[4,] 0 0 0 1 0
[5,] 0 0 0 0 1
上面這種主對角元素為 1, 其餘元素均為 0 之矩陣稱為
單位矩陣 I (unitary matrix). 單位矩陣之特徵值為 1, 任何矩陣與單位矩陣之內積等於本身, 即 :
A %*% I=A
I %*% A=A
下面這個 1*5 矩陣看起來像向量, 實際上是矩陣 (結構不同).
> diag(1, ncol=5) #nrow 預設為 1, 故建立 1*5 矩陣
[,1] [,2] [,3] [,4] [,5]
[1,] 1 0 0 0 0
> class(diag(1, ncol=5))
[1] "matrix"
不是方陣之對角矩陣 :
> diag(1, nrow=5, ncol=3)
[,1] [,2] [,3]
[1,] 1 0 0
[2,] 0 1 0
[3,] 0 0 1
[4,] 0 0 0
[5,] 0 0 0
> diag(1, nrow=3, ncol=5)
[,1] [,2] [,3] [,4] [,5]
[1,] 1 0 0 0 0
[2,] 0 1 0 0 0
[3,] 0 0 1 0 0
diag() 函數第一參數傳入向量時會套用璇還規則 :
> diag(c(1,2), nrow=5) #x=向量時套用循環規則在對稱軸上
[,1] [,2] [,3] [,4] [,5]
[1,] 1 0 0 0 0
[2,] 0 2 0 0 0
[3,] 0 0 1 0 0
[4,] 0 0 0 2 0
[5,] 0 0 0 0 1
> diag(1:6, nrow=5)
[,1] [,2] [,3] [,4] [,5]
[1,] 1 0 0 0 0
[2,] 0 2 0 0 0
[3,] 0 0 3 0 0
[4,] 0 0 0 4 0
[5,] 0 0 0 0 5
diag() 函數第一參數也可以傳入矩陣, 它會傳回矩陣對角元素形成之向量, 例如 :
> A <- matrix(1:16, nrow=4)
> A
[,1] [,2] [,3] [,4]
[1,] 1 5 9 13
[2,] 2 6 10 14
[3,] 3 7 11 15
[4,] 4 8 12 16
> v=diag(A) #傳回對角元素
> v
[1] 1 6 11 16
> class(v) #diag(A) 傳回向量
[1] "integer"
> is.vector(v)
[1] TRUE
二. 存取矩陣元素 :
與存取向量類似, 存取矩陣也是使用中 (方) 括號, 但矩陣要用兩維 m[i, j], 第一索引 i 是列, 第二索引 j 是行. 例如 :
> m=matrix(1:12, 4,3)
> dimnames(m) <- list(c("R1","R2","R3","R4"),c("C1","C2","C3"))
> m
C1 C2 C3
R1 1 5 9
R2 2 6 10
R3 3 7 11
R4 4 8 12
> m[2,2] #取得第 2 列第 2 行元素
[1] 6
> m[2,]
C1 C2 C3
2 6 10
> m[,2] #取得第 2 行元素
R1 R2 R3 R4
5 6 7 8
> m[2,c(2,3)] #取得第 2 列第 2, 3 行元素
C2 C3
6 10
> m[c(3,4),2] #取得第 3, 4 列第 2 行元素
R3 R4
7 8
> m[3:4,2] #取得第 3~4 列第 2 行元素
R3 R4
7 8
若取出之元素若維度小於 2 (例如某列或行中的幾個元素) 會降階為原型向量; 若維度等於 2 則仍為矩陣 (子矩陣).
從矩陣中取出元素時若要保留矩陣類型可在中括號內指定 drop=FALSE, 例如 :
> class(m[2,]) #取出的資料維度小於 1 變成向量
[1] "numeric"
> class(m[,2]) #取出的資料維度小於 1 變成向量
[1] "numeric"
> class(m[2:3,2:3]) #取出的資料維度等於 1 仍為矩陣
[1] "
matrix"
> (m[2, , drop=FALSE])
C1 C2 C3
R2 2 6 10
> class(m[,2,
drop=FALSE]) #取出元素時不降階, 仍為矩陣類型
[1] "matrix"
> (m[,2,drop=FALSE])
C2
R1 5
R2 6
R3 7
R4 8
> class(m[2, ,
drop=FALSE]) #取出元素時不降階, 仍為矩陣類型
[1] "matrix"
存取矩陣元素可以使用負索引來排除不要的列或行, 負索引只是在查詢時排除特定元素而已, 原矩陣不受影響. 例如 :
> m[-2, -2] #不要顯示第 2 列第 2 行元素
C1 C3
R1 1 9
R3 3 11
R4 4 12
> m # 原矩陣不受影響
C1 C2 C3
R1 1 5 9
R2 2 6 10
R3 3 7 11
R4 4 8 12
> m[-c(2,3), -2] #不要顯示第 2, 3 列第 2 行元素
C1 C3
R1 1 9
R4 4 12
> m[-c(2:3), -2] #不要顯示第 2~3 列第 2 行元素
C1 C3
R1 1 9
R4 4 12
修改矩陣元素之值只要用設定運算子將向量指派給矩陣元素即可, 例如 :
> m[2:3, ] <- 99 #第 2~3 列改為 99
> m
C1 C2 C3
R1 1 5 9
R2
99 99 99
R3
99 99 99
R4 4 8 12
> m[1,] <- NA #第 1 列改為 NA
> m
C1 C2 C3
R1
NA NA NA
R2 99 99 99
R3 99 99 99
R4 4 8 12
> m[, 3] <-
c(4, 5) #第 3 行改為 c(4, 5) 套用循環規則
> m
C1 C2 C3
R1 NA NA
4
R2 99 99
5
R3 99 99
4
R4 4 8
5
三. 矩陣的運算 :
1. 四則運算 :
矩陣與一個純量的加減乘除運算會作用在每一個元素上, 例如 :
gt; matrix(1:12, nrow=3)
[,1] [,2] [,3] [,4]
[1,] 1 4 7 10
[2,] 2 5 8 11
[3,] 3 6 9 12
> matrix(1:12, nrow=3) + 1
[,1] [,2] [,3] [,4]
[1,] 2 5 8 11
[2,] 3 6 9 12
[3,] 4 7 10 13
> matrix(1:12, nrow=3) - 1
[,1] [,2] [,3] [,4]
[1,] 0 3 6 9
[2,] 1 4 7 10
[3,] 2 5 8 11
> matrix(1:12, nrow=3) * 2
[,1] [,2] [,3] [,4]
[1,] 2 8 14 20
[2,] 4 10 16 22
[3,] 6 12 18 24
> matrix(1:12, nrow=3) / 2
[,1] [,2] [,3] [,4]
[1,] 0.5 2.0 3.5 5.0
[2,] 1.0 2.5 4.0 5.5
[3,] 1.5 3.0 4.5 6.0
兩個矩陣也可以做四則運算, 即
對應的元素做加減乘除運算, 但先決條件是
維度須一樣, 即列數相同, 行數相同, 否則會出現 "非調和陣列" 的錯誤訊息, 例如 :
&> A <- matrix(1:12, nrow=3)
> A
[,1] [,2] [,3] [,4]
[1,] 1 4 7 10
[2,] 2 5 8 11
[3,] 3 6 9 12
> B <- matrix(1:12, nrow=3)
> B
[,1] [,2] [,3] [,4]
[1,] 1 4 7 10
[2,] 2 5 8 11
[3,] 3 6 9 12
> A+B #矩陣相加為對應元素相加
[,1] [,2] [,3] [,4]
[1,] 2 8 14 20
[2,] 4 10 16 22
[3,] 6 12 18 24
> A-B #矩陣相減為對應元素相減
[,1] [,2] [,3] [,4]
[1,] 0 0 0 0
[2,] 0 0 0 0
[3,] 0 0 0 0
> A*B #矩陣相乘為對應元素相乘 (
Hardamard 乘積)
[,1] [,2] [,3] [,4]
[1,] 1 16 49 100
[2,] 4 25 64 121
[3,] 9 36 81 144
> A/B #矩陣相除為對應元素相除
[,1] [,2] [,3] [,4]
[1,] 1 1 1 1
[2,] 1 1 1 1
[3,] 1 1 1 1
> C <- matrix(1:12, nrow=4) #C 為 4 列 3 行矩陣
> C
[,1] [,2] [,3]
[1,] 1 5 9
[2,] 2 6 10
[3,] 3 7 11
[4,] 4 8 12
> A+C #C 為 4 列 3 行矩陣, A 為 3 列 4 行矩陣, 維度不同無法運算
Error in A + C :
非調和陣列
另外, 矩陣也可以與向量做四則運算, 但條件是
向量的長度必須與矩陣的列數相同, 例如 :
> A <- matrix(1:6, nrow=3) #矩陣 A 為 3 列 2 行
> A
[,1] [,2]
[1,] 1 4
[2,] 2 5
[3,] 3 6
> A + 1:3 #向量長度為 3, 與矩陣列數相同 : 可四則運算
[,1] [,2]
[1,] 2 5
[2,] 4 7
[3,] 6 9
> 1:3 + A
[,1] [,2]
[1,] 2 5
[2,] 4 7
[3,] 6 9
> A - 1:3
[,1] [,2]
[1,] 0 3
[2,] 0 3
[3,] 0 3
> 1:3 - A
[,1] [,2]
[1,] 0 -3
[2,] 0 -3
[3,] 0 -3
> A * 1:3
[,1] [,2]
[1,] 1 4
[2,] 4 10
[3,] 9 18
> 1:3 * A
[,1] [,2]
[1,] 1 4
[2,] 4 10
[3,] 9 18
> A / 1:3
[,1] [,2]
[1,] 1 4.0
[2,] 1 2.5
[3,] 1 2.0
> 1:3 / A
[,1] [,2]
[1,] 1 0.25
[2,] 1 0.40
[3,] 1 0.50
可見此向量是跟矩陣的每一行做運算的, 因此可以把向量看成是列向量 (雖然 R 語言的向量並無維度). 其實
向量的長度只要不大於矩陣的列數就可以, 這時運算時會套用循環規則, 例如 :
> A
[,1] [,2]
[1,] 1 4
[2,] 2 5
[3,] 3 6
> A + 1:2 #向量長度為 2 < 矩陣列數 3 (套用循環規則)
[,1] [,2]
[1,] 2 6
[2,] 4 6
[3,] 4 8
> A + 1:4 #向量長度為 4 > 矩陣列數 3 (無法運算)
[,1] [,2]
[1,] 2 8
[2,] 4 6
[3,] 6 8
Warning message:
In A + 1:4 :
較長的物件長度並非較短物件長度的倍數
這裡 A + 1:2 的第一行 [2 4 4] 是 [1 2 3] + [1 2 1] 而得, 其餘類推.
2. 矩陣的內積 :
上面的 A*B 稱為
阿達馬乘積 (
Hardamard 乘積), 兩個矩陣 A 與 B 的阿達馬乘積 A*B 是對應元素相乘, 其條件是兩矩陣的維度必須相同 (即均為 m*n 矩陣); 而矩陣的內積 A%*%B 則是 A 的列與 B 的行元素的對應乘積和組成的矩陣, 因此
內積可乘之條件是矩陣 A 的列數須等於矩陣 B 的行數, 亦即若矩陣 A 為 m*n, 矩陣 B 為 n*p, 則 A%*%B 結果將得到一個 m*p 的矩陣, 維度相等之方陣必定是內積可乘. 例如 :
> A <- matrix(1:6,
nrow=3) #A 為 3*2 矩陣
> A
[,1] [,2]
[1,] 1 4
[2,] 2 5
[3,] 3 6
> B <- matrix(1:6,
nrow=2) #B 為 2*3 矩陣
> B
[,1] [,2] [,3]
[1,] 1 3 5
[2,] 2 4 6
> A %*% B #A 與 B 之內積
[,1] [,2] [,3]
[1,] 9 19 29
[2,] 12 26 40
[3,] 15 33 51
> B %*% A #B 與 A 之內積
[,1] [,2]
[1,] 22 49
[2,] 28 64
執行 A 與 B 之內積運算時, A 的第一列元素與 B 的第一行對應相乘再相加, 1*1 + 4*2=9 即為結果矩陣之 [1,1] 元素, 其餘類推.
若兩個矩陣 A, B 均有行列名稱且內積可乘, 則其
內積 A%*% B 將保留前者 A 的列名與後者 B 的行名作為結果矩陣之行列名稱, 例如 :
> A=matrix(1:12, 4) #A 為 4*3 矩陣
> rownames(A) <- c("R1","R2","R3","R4")
> colnames(A) <- c("C1","C2","C3")
> A
C1 C2 C3
R1 1 5 9
R2 2 6 10
R3 3 7 11
R4 4 8 12
> B=matrix(1:12, 3) #B 為 3*4 矩陣
> rownames(B) <- c("1st","2nd","3rd")
> colnames(B) <-
LETTERS[1:4] #使用大寫字母向量
> B
A B C D
1st 1 4 7 10
2nd 2 5 8 11
3rd 3 6 9 12
> A %*% B # A 與B 內積會保留 A 之列名與 B 之行名
A B C D
R1 38 83 128 173
R2 44 98 152 206
R3 50 113 176 239
R4 56 128 200 272
3. 轉置矩陣運算 t() :
所謂轉置矩陣是將矩陣的列與行互換所成之矩陣, R 語言提供 t() 函數可執行轉置運算 (transpose), 例如 :
> A <- matrix(1:12, nrow=3)
> A
[,1] [,2] [,3] [,4]
[1,] 1 4 7 10
[2,] 2 5 8 11
[3,] 3 6 9 12
> t(A)
[,1] [,2] [,3]
[1,] 1 2 3
[2,] 4 5 6
[3,] 7 8 9
[4,] 10 11 12
一個矩陣 A 與其轉置矩陣 t(A) 因其行列互換後相同必定是內積可乘, 不論 A %*% t(A) 或 t(A) %*% 均可乘, 例如 :
> A %*% t(A)
[,1] [,2] [,3]
[1,] 166 188 210
[2,] 188 214 240
[3,] 210 240 270
> t(A) %*% A
[,1] [,2] [,3] [,4]
[1,] 14 32 50 68
[2,] 32 77 122 167
[3,] 50 122 194 266
[4,] 68 167 266 365
矩陣若有行列名稱, 則轉置時也會隨同轉置, 例如 :
> A=matrix(1:12, 4)
> rownames(A) <- c("R1","R2","R3","R4")
> colnames(A) <- c("C1","C2","C3")
> A
C1 C2 C3
R1 1 5 9
R2 2 6 10
R3 3 7 11
R4 4 8 12
> t(A) #轉置時行列名稱也會一起轉置
R1 R2 R3 R4
C1 1 2 3 4
C2 5 6 7 8
C3 9 10 11 12
4. 矩陣元素和與平均值運算 :
R 語言中提供下列函數計算矩陣之行列和與平均值 :
rowSums(x)
計算列總和
colSums(x)
計算行總和
rowMeans(x)
計算列平均
colMeans(x)
計算行平均
sum(x)
計算矩陣全部元素和
mean(x)
計算矩陣全部元素平均值
例如 :
> A <- matrix(1:6, nrow=2)
> A
[,1] [,2] [,3]
[1,] 1 3 5
[2,] 2 4 6
> rowSums(A)
[1] 9 12
> colSums(A)
[1] 3 7 11
> rowMeans(A)
[1] 3 4
> colMeans(A)
[1] 1.5 3.5 5.5
> sum(A)
[1] 21
> mean(A)
[1] 3.5
5. 用 det() 求矩陣之行列式值 :
行列式 (determinant) 是將方陣映射到一個純量的函數, 其值為方陣中向右對角線元素乘積和減向左對角線元素乘積和, 可用 det() 函數求得, 例如
> A <- matrix(1:4, 2)
> A
[,1] [,2]
[1,] 1 3
[2,] 2 4
> det(A)
[1] -2
> A=matrix(1:9, 3)
> A
[,1] [,2] [,3]
[1,] 1 4 7
[2,] 2 5 8
[3,] 3 6 9
> det(A)
[1] 0
注意. 只有方陣才有行列式值 :
> A <- matrix(1:6, 2)
> A
[,1] [,2] [,3]
[1,] 1 3 5
[2,] 2 4 6
> det(A) #
Error in determinant.matrix(x, logarithm = TRUE, ...) :
'x' must be a square matrix
6. 用 solve() 函數求逆矩陣 :
所謂逆矩陣是指, 若一個 n 階方陣 A, 存在一個 n 階方陣 B 使得 A 與 B 之內積為一 n 階單位方陣, 則稱 A 為可逆, 而 B 為其逆矩陣. 注意, 可逆矩陣一定是方陣, 但方陣並不一定是可逆, 只有非奇異方陣 (即其行列式值不為 0 者) 才有逆矩陣, 參考 :
#
https://zh.wikipedia.org/wiki/逆矩阵
例如 :
> A=matrix(1:4, 2)
> A
[,1] [,2]
[1,] 1 3
[2,] 2 4
> solve(A)
[,1] [,2]
[1,] -2 1.5
[2,] 1 -0.5
逆矩陣是很重要的矩陣運算, 例如在解線性方程組 Ax=B 時就要用到反矩陣, R 語言提供 solve() 函數來計算反矩陣 :
x=solve(A) %*% B
例如下列二元一次方程組 :
x + 3y=4
2x + 4y=6
其解即可用係數矩陣之逆矩陣與常數項矩陣之內積求得 :
> solve(A) %*% matrix(c(4,6), nrow=2)
[,1]
[1,] 1
[2,] 1
> solve(A) %*% c(4,6) #用向量也可以 matrix(c(4,6), nrow=2)
[,1]
[1,] 1
[2,] 1
即其解為 x=1, y=1.
7. 用 eigen() 求特徵值與特徵向量 :
一個方陣 (square matrix) A 的特徵向量 V 是指 V 經過方陣 A 的線性變換後, 結果與 V 保持純量關係, 即 AV=eV, 其中 e 為一純量, 代表向量 V 經過線性變換後之縮放比例, 特徵值為正表示向量 V 方向不變; 反之為負表示方向相反. e 稱為方陣 A 之特徵值, V 為其特徵向量, 參考 :
#
https://zh.wikipedia.org/wiki/特征值和特征向量
> A <- matrix(1:12, nrow=4) #建立 4*3 矩陣 (非方陣)
> eigen(A)
Error in eigen(A) :
non-square matrix in 'eigen' #方陣才有特徵值
> A <- matrix(1:9, nrow=3) #建立 3*3 方陣
> eigen(A) #計算特徵值與特徵向量
eigen() decomposition
$
values #特徵值
[1] 1.611684e+01 -1.116844e+00 -5.700691e-16
$
vectors #特徵向量
[,1] [,2] [,3]
[1,] -0.4645473 -0.8829060 0.4082483
[2,] -0.5707955 -0.2395204 -0.8164966
[3,] -0.6770438 0.4038651 0.4082483
>
V["values"] #取得特徵值
$values
[1] 1.611684e+01 -1.116844e+00 -1.303678e-15
>
V["vectors"] #取得特徵向量
$vectors
[,1] [,2] [,3]
[1,] -0.2319707 -0.78583024 0.4082483
[2,] -0.5253221 -0.08675134 -0.8164966
[3,] -0.8186735 0.61232756 0.4082483
> V <- eigen(A)
> class(V)
[1] "
eigen"
> class(V["values"]) #特徵值是 list 類型
[1] "
list"
> class(V["vectors"]) #特徵向量是 list 類型
[1] "
list"
可知 eigen() 函數傳回值為 eigen 類型之物件, 其內有 values (特徵值) 與 vectors (特徵向量) 兩個屬性, 都是 list 類型資料.
四. 矩陣常用函數 :
與矩陣相關之常用函數如下表 :
函數 | 說明 |
matrix(data, nrow, ncol, byro) | |
str(x) | 顯示物件結構與內容 |
length(x) | 顯示矩陣元素個數 |
dim(x) | 顯示物件 (矩陣, 陣列, 資料框) 維度 |
nrow(x) | 顯示矩陣列數 |
ncol(x) | 顯示矩陣行數 |
is.matrix(x) | 檢查是否為矩陣類型 |
as.matrix(x) | 將物件強制轉型為矩陣類型 |
rbind(v1, v2, ...) | 將多個向量以列向量方式組成矩陣 |
cbind(v1, v2, ...) | 將多個向量以行向量方式組成矩陣 |
diag(x=1, nrow, ncol) | 以 x 為軸建立 nrow 列, ncol 行之矩陣 (nrow=ncol 時對稱) |
rownames(x) | 取得矩陣的列名 |
colnames(x) | 取得矩陣的行名 |
dimnames(x) | 取得矩陣的維度資訊 (含列名與欄名) |
rowSums(x) | 計算矩陣列總和 |
colSums(x) | 計算矩陣行總和 |
rowMeans(x) | 計算矩陣列平均 |
colMeans(x) | 計算矩陣行平均 |
sum(x) | 計算矩陣全部元素和 |
mean(x) | 計算矩陣全部元素平均值 |
det(x) | 計算方陣之行列式值 |
solve(x) | 求方陣之逆矩陣 |
eigen(x) | 計算矩陣之特徵值與特徵向量 |
參考 :
#
R语言基础:矩阵
#
利用 matrix 建立矩陣
#
矩阵基本操作
#
R Tutorial : matrix
#
R 向量、矩陣與陣列