在 R 語言中,我們已經認識了向量這個基礎資料結構,它像是一條直線,能夠儲存一系列相同型別的資料。但隨著資料分析的複雜度增加,單純的一維結構往往不敷使用。這時候,矩陣(matrix)便成為我們必須掌握的工具。如果說向量是一條線,那麼矩陣就像是一張表格,讓我們能夠以更有條理的方式組織與分析資料。
矩陣初探:從一維到二維的跨越
碰到矩陣的第一個疑問是:「為何我們需要多一個維度?」想像你正在分析一所學校三個班級、五個學生的數學考試成績。如果使用向量,你可能需要多個向量來儲存:
1 | class1_scores <- c(85, 90, 78, 92, 88) |
管理這麼多向量不僅繁瑣,還容易出錯。矩陣則提供了一個更優雅的解決方案:
1 | all_scores <- matrix(c(85, 90, 78, 92, 88, |
[,1] [,2] [,3] [,4] [,5]
[1,] 85 90 78 92 88
[2,] 76 82 91 64 85
[3,] 92 78 85 90 73
這樣,我們就將三個班級的成績整合到一個矩陣中,每一列代表一個班級,每一行代表班級中的某位學生。資料的組織變得更加直觀與系統化。在數學上,矩陣是一個由數字排列成的長方形陣列,其中的元素按照行與列整齊排列。通常以下列形式表示:
$$
A = \begin{bmatrix}
a_{11} & a_{12} & \cdots & a_{1n}\\
a_{21} & a_{22} & \cdots & a_{2n}\\
\vdots & \vdots & \ddots & \vdots\\
a_{m1} & a_{m2} & \cdots & a_{mn}
\end{bmatrix}
$$
這個表示法中:
- $A$ 是矩陣的名稱
- $a_{ij}$ 表示位於第 $i$ 列第 $j$ 行的元素
- $m$ 是矩陣的列數(rows)
- $n$ 是矩陣的行數(columns)
我們通常會說 $A$ 是一個 $m \times n$ 矩陣(念作「$m$ by $n$」矩陣),表示它有 $m$ 列和 $n$ 行。在 R 語言中,矩陣同樣遵循這一定義,但有幾個重要特性需要特別注意:
- 同質性(homogeneity):矩陣中的所有元素必須屬於相同的資料型別,無論是數值型、字元型還是邏輯型。
- 二維結構:矩陣有兩個維度 — 列與欄。
- 有序性:矩陣中的每個元素都有明確的位置,可以通過行索引與列索引來定位。
有了這些好的特性,矩陣便成為處理表格式資料的理想結構,尤其是當資料具有數值性質且需要進行數學運算時。
矩陣建立:matrix()
函數的魔法
建立矩陣是進入二維資料分析的第一步,而在 R 語言中,matrix()
函數就像是一個變形金剛,能將一維向量轉變為井然有序的二維結構。無論你是需要整理實驗數據、分析問卷結果,還是進行複雜的統計運算,掌握 matrix()
的使用方法都是不可或缺的基本技能。
矩陣建立的基本語法
在 R 語言中,建立矩陣的最基本方法是使用 matrix() 函數。其基本語法如下:
1 | matrix(data = NA, nrow = 1, ncol = 1, byrow = FALSE, dimnames = NULL) |
這裡的參數分別代表:
- data:用來填充矩陣的資料,通常是一個向量
- nrow:矩陣的列數
- ncol:矩陣的行數
- byrow:資料填充方式,預設為 FALSE(按列填充)
- dimnames:矩陣的維度名稱(行名和列名)
讓我們從最簡單的例子開始,建立一個 $2 \times 3$ 的矩陣:
1 | m1 <- matrix(1:6, nrow = 2, ncol = 3) |
[,1] [,2] [,3]
[1,] 1 3 5
[2,] 2 4 6
可以看到,R 預設是按照「列」的方向填充資料(即先填滿第一列,再填第二列…)。這與我們平常閱讀的習慣(從左到右,從上到下)有些不同,因此在建立矩陣時需要特別注意。
元素填充的藝術:byrow
參數的秘密
如果想改變填充方式,使其符合我們習慣的閱讀順序(先填滿第一列,再往下),可以設定 byrow = TRUE
:
1 | m2 <- matrix(1:6, nrow = 2, ncol = 3, byrow = TRUE) |
[,1] [,2] [,3]
[1,] 1 2 3
[2,] 4 5 6
這樣一來,資料就按照我們熟悉的方式排列了。在實際應用中,選擇哪種填充方式取決於你的資料結構和分析需求。例如,當處理時間序列資料時,可能希望每一列代表一個時間點的不同觀測值;而分析問卷資料時,可能希望每一列代表一位受訪者的所有回答。
維度設計:塑造矩陣的形狀
在建立矩陣時,你只需要指定 nrow
或 ncol
中的一個,R 會自動計算另一個維度。例如:
1 | # 只指定列數 |
[,1] [,2] [,3] [,4] [,5]
[1,] 1 3 5 7 9
[2,] 2 4 6 8 10
[,1] [,2] [,3] [,4] [,5]
[1,] 1 3 5 7 9
[2,] 2 4 6 8 10
可以發現兩者的結果其實是相同的。然而,需要注意的是,如果向量長度不是列數和行數的乘積,R 會重複使用向量中的元素來填滿矩陣,並可能發出警告訊息。
1 | m5 <- matrix(1:5, nrow = 3, ncol = 4) |
Warning message in matrix(1:5, nrow = 3, ncol = 4):
“data length [5] is not a sub-multiple or multiple of the number of rows [3]”
[,1] [,2] [,3] [,4]
[1,] 1 4 2 5
[2,] 2 5 3 1
[3,] 3 1 4 2
此時 R 會顯示警告:「資料長度 [5]
不是行數 [3]
與列數 [4]
的乘積」,並循環使用資料來填滿矩陣。雖然程式不會報錯,但這種情況可能導致資料誤解,因此在實際應用中應盡量避免。
從現有資料建立矩陣
除了從頭建立矩陣外,也可以將現有的向量轉換為矩陣:
1 | # 三個班級的數學、英文、自然考試分數 |
[,1] [,2] [,3]
[1,] 85 90 78
[2,] 76 82 91
[3,] 92 78 85
這裡每一列代表一個班級,每一行代表一個科目。但這樣的排列方式並不直觀,如果希望每列代表一個科目,可以使用 byrow = TRUE
或者更簡單的方法——轉置矩陣(transpose matrix):
1 | scores_t <- t(scores) # t() 函數用於矩陣轉置 |
[,1] [,2] [,3]
[1,] 85 76 92
[2,] 90 82 78
[3,] 78 91 85
現在每列代表一個科目,每行代表一個班級,資料的組織方式更加符合我們的直覺。
常見矩陣創建陷阱與解決方案
在使用 matrix()
函數時,有幾個常見的陷阱需要注意。首先是資料型別混合,矩陣只能包含同一種資料型別。如果混合不同型別的資料,R 會自動轉換成最通用的型別:
1 | mixed <- matrix(c(1, 2, "3", TRUE), nrow = 2) |
[,1] [,2]
[1,] "1" "3"
[2,] "2" "TRUE"
[1] "character"
可以看到,所有元素都被轉換成了字元型。另一個則是維度不匹配,前面已經提到,如果資料長度不是列數和行數的乘積,R 會重複使用資料並發出警告。為避免這種情況,可以事先確認資料長度是否匹配,或者使用 rep()
函數有意識地複製資料。最後一個則是填充順序混淆,預設的 byrow = FALSE
可能與我們的直覺不符。解決方法是養成習慣,明確指定 byrow
參數,或者在建立後使用 t()
函數轉置矩陣。
效率。
矩陣的命名系統:為數字賦予意義
在資料分析的過程中,我們不僅需要關注數字本身,更需要理解這些數字背後的含義。就像一張街道地圖需要標明道路名稱才能幫助人們找到目的地,矩陣中的資料也需要適當的標籤才能讓我們清楚地解讀其中的資訊。在 R 語言中,我們可以透過行列命名,讓矩陣從單純的數字陣列轉變為具有明確語意的資料結構。
行列有名:讓數據說故事
想像你正在分析不同城市的氣象資料,有溫度、濕度和降雨量三種指標。如果將這些資料放入一個無標籤的矩陣中,每次讀取資料時都需要記住「第一行是台北、第二行是高雄、第一列是溫度、第二列是濕度…」,這不僅容易出錯,還會增加認知負擔。透過行列命名,我們可以讓矩陣變得更加直觀:
1 | # 建立原始矩陣:3個城市的3種氣象指標 |
台北 高雄 台中
溫度 25 28 23
濕度 78 85 80
降雨量 10 15 20
如此一來,矩陣不僅是一堆數字,而是一個承載著明確意義的資料結構。我們可以直觀地看出台北的溫度是25度,高雄的濕度是85%,而不需要靠記憶位置來辨識資料。
dimnames()
、rownames()
與 colnames()
的巧妙運用
在 R 中,為矩陣命名有多種方法,最常用的是 rownames()
、colnames()
和 dimnames()
這三個函數。
rownames()
用於設定或獲取矩陣的列名colnames()
用於設定或獲取矩陣的行名dimnames()
則可以同時設定列名和行名
我們可以在建立矩陣時直接指定名稱:
1 | # 使用 dimnames 參數直接命名 |
數學 英文 自然
小明 85 90 78
小華 76 82 91
小美 92 78 85
或者在建立矩陣後再設定名稱:
1 | # 先建立矩陣 |
產品A 產品B 產品C
1月 150 200 300
2月 120 220 250
3月 180 230 270
另外,如果只想查看或修改某一維度的名稱,可以分別使用 rownames()
或 colnames()
:
1 | # 查看列名 |
[1] "1月" "2月" "3月"
手機 筆電 平板
1月 150 200 300
2月 120 220 250
3月 180 230 270
命名對資料解讀的幫助
良好的行列命名不僅讓資料更易讀,還能大幅提升資料分析的效率與準確性。第一個好處就是能夠直觀選取資料,有了名稱,我們可以直接用名字而非索引來選取資料,程式碼更加清晰易懂:
1 | # 使用名稱選取特定元素 |
[1] 85
數學 英文 自然
76 82 91
小明 小華 小美
90 82 78
另一個就是不用花時間寫一大堆註解,直接用名稱,程式碼就能自我解釋:
1 | january_tablet_sales <- sales_data["1月", "平板"] |
[1] 300
再來,當矩陣有名稱後,當需要合併或比較不同矩陣的資料時,名稱可作為對齊的依據:
1 | # 上半年與下半年的銷售資料 |
手機 筆電 平板
1月 150 200 300
2月 120 220 250
3月 180 230 270
7月 160 210 280
8月 140 230 260
9月 190 240 290
矩陣索引技巧
在介紹向量時已經提過,利用索引,我們可以將所需要的資料從向量中提取出來。矩陣也不例外,讓我們能夠在這個數字表格中定位並取出特定的元素、列或行。
矩陣定位的藝術:[列, 欄]
系統
R 語言中的矩陣索引遵循 [列, 欄] 的格式,這與我們日常使用的座標系統有些類似,只是順序是先「列」再「欄」。這種順序設計是因為在統計分析中,我們通常將每一列視為一個獨立的觀測單位,而列的優先順序符合這種思維方式。最基本的索引方式是使用數字位置:
1 | # 建立一個矩陣 |
[,1] [,2] [,3] [,4]
[1,] 1 2 3 4
[2,] 5 6 7 8
[3,] 9 10 11 12
[1] 7
[1] 1 2 3 4
[1] 4 8 12
注意,當我們只選取一個列或一個行時,R 預設會將結果簡化為一個向量。如果希望保持矩陣結構,可以使用 drop = FALSE
參數:
1 | # 保持矩陣結構 |
[,1] [,2] [,3] [,4]
[1,] 1 2 3 4
靈活選取:單元素、整列、整欄的擷取方法
矩陣索引的強大之處在於它的靈活性。我們可以一次選取多個元素、多列或多欄,甚至是不連續的部分。使用向量作為索引,可以實現這種靈活選取:
1 | # 建立一個有名稱的矩陣 |
數學 英文 自然 社會
小明 85 90 78 92
小華 76 82 91 88
小美 92 78 85 95
數學 自然
小明 85 78
小美 92 85
小明 小華 小美
90 82 78
數學 英文 自然 社會
76 82 91 88
甚至可以使用負號來排除特定的列或行:
1 | # 排除小華的成績 |
數學 英文 自然 社會
小明 85 90 78 92
小美 92 78 85 95
數學 自然
小明 85 78
小華 76 91
小美 92 85
條件式索引:以邏輯向量篩選矩陣資料
矩陣索引的另一個強大功能是可以使用邏輯條件進行篩選。這讓我們能夠提取符合特定條件的資料,非常適合用於資料分析中的篩選與子集選取。
1 | # 找出所有大於 85 分的成績 |
數學 英文 自然 社會
小明 FALSE TRUE FALSE TRUE
小華 FALSE FALSE TRUE TRUE
小美 TRUE FALSE FALSE TRUE
數學 英文 自然 社會
小明 "良" "優" "良" "優"
小華 "良" "良" "優" "優"
小美 "優" "良" "良" "優"
我們也可以使用邏輯條件直接提取符合條件的元素:
1 | # 提取所有大於 85 分的成績 |
[1] 92 90 91 92 88 95
需要注意的是,使用這種方式提取的結果是一個向量,而不是矩陣,因為它只保留了符合條件的單個元素,而不是行或列。
命名索引:用欄位名稱導航
如果矩陣已經有了行列名稱,我們可以直接使用這些名稱進行索引,這比使用數字位置更直觀,也更不容易出錯:
1 | # 使用名稱索引選取特定學生的特定科目 |
[1] 91
數學 社會
小明 85 92
小美 92 95
名稱索引的一個優勢是,即使矩陣的結構發生變化(如行列順序調整),只要名稱不變,程式碼仍然能正確執行。這在處理動態變化的資料時特別有用。
矩陣進階索引技巧
當然還有一些更進階的索引技巧,可以在複雜的資料分析場景中更有效地處理矩陣。首先是使用 which()
函數找出特定位置:
1 | # 找出所有大於 90 分的成績位置 |
row col
小美 3 1
小華 2 3
小明 1 4
小美 3 4
另一個是使用 apply()
函式進行行或列操作,apply() 函式可以對矩陣的行或列應用指定函數,與索引結合使用,能夠實現更複雜的批次處理:
1 | # 計算每個學生的平均分數 |
小明 小華 小美
86.25 84.25 87.50
[1] "小明" "小美"
對於方陣(行列數相等的矩陣),diag()
函式可以提取或設定對角線元素:
1 | # 建立一個方陣 |
[,1] [,2] [,3]
[1,] 1 4 7
[2,] 2 5 8
[3,] 3 6 9
[1] 1 5 9
[,1] [,2] [,3]
[1,] 0 4 7
[2,] 2 0 8
[3,] 3 6 0
矩陣的合縱連橫:rbind()
與 cbind()
的應用
在實際的資料分析過程中,我們經常需要將多個資料集合併或擴展現有的資料結構。就像拼圖一樣,有時候需要橫向添加新的片段,有時候需要縱向增加新的行列。而在 R 語言中,rbind()
和 cbind()
這兩個函式就像是巧妙的拼接工具,讓我們能夠靈活地組合和擴展矩陣資料。
橫向擴展:以 cbind()
添加新欄位
cbind()
函式的名稱源自行合併(column bind),它可以將多個向量或矩陣「橫向」合併,也就是增加新的行(欄位)。這在需要為現有資料添加新變數或特徵時尤其有用。基本用法如下:
1 | # 建立初始矩陣:學生的數學和英文成績 |
數學 英文
小明 85 90
小華 76 82
小美 92 78
數學 英文 自然
小明 85 90 78
小華 76 82 91
小美 92 78 85
注意到,我們在 cbind()
中直接使用了 自然 = science
的語法,這不僅合併了資料,還同時為新增的欄位命名,使結果更加直觀。cbind()
也可以一次合併多個向量或矩陣:
1 | # 一次性新增自然和社會兩科成績 |
數學 英文 自然 社會
小明 85 90 78 92
小華 76 82 91 88
小美 92 78 85 95
縱向成長:用 rbind()
增加新資料列
與 cbind()
相對,rbind()
函式來源於列合併(row bind),用於將多個向量或矩陣「縱向」合併,也就是增加新的列(觀測值)。這在需要合併多個資料集或隨時間積累新資料時特別實用。基本用法如下:
1 | # 繼續使用上面的學生成績矩陣 |
數學 英文
小明 85 90
小華 76 82
小美 92 78
數學 英文
小明 85 90
小華 76 82
小美 92 78
小強 88 94
和 cbind()
類似,rbind()
也可以在合併時直接命名,並可一次合併多個向量或矩陣:
1 | # 一次性新增兩位學生的成績 |
數學 英文
小明 85 90
小華 76 82
小美 92 78
小強 88 94
小雯 79 85
合併的藝術:確保維度一致性
使用 rbind()
和 cbind()
進行合併時,必須確保矩陣的維度是匹配的:
- 對於
rbind()
,所有要合併的矩陣或向量必須有相同的列數(欄位數一致) - 對於
cbind()
,所有要合併的矩陣或向量必須有相同的行數(觀測值數量一致)
如果維度不匹配,R 會嘗試自動調整(如循環使用較短的向量),但這可能導致不符合預期的結果或錯誤。例如:
1 | # 嘗試添加維度不匹配的資料 |
[,1] [,2] [,3]
[1,] 85 90 78
[2,] 76 82 91
[3,] 92 78 85
Warning message in cbind(scores, c(78, 91)):
“number of rows of result is not a multiple of vector length (arg 2)”
[,1] [,2] [,3]
[1,] 85 90 78
[2,] 76 82 91
[3,] 92 78 78
在第二個例子中,由於向量長度 (2)
小於矩陣的列數 (3)
,R 自動循環使用向量的元素來填充,導致最後一個元素是重複的 78,這可能不是我們想要的結果。
矩陣合併的注意事項
在使用 rbind()
和 cbind()
進行矩陣合併時,有幾點需要特別注意。第一個仍是資料型別必須具有一致性,矩陣中的所有元素必須是相同型別。如果合併的資料型別不一致,R 會自動將所有元素轉換為最通用的型別:
1 | # 合併不同型別的資料 |
[,1] [,2] [,3]
[1,] "1" "3" "a"
[2,] "2" "4" "b"
[1] "character"
可以看到,原本的數值被轉換成了字元型,這在後續的數值計算中可能會造成問題。第二個則是維度匹配與名稱保留,由於 rbind()
和 cbind()
會盡可能保留原始矩陣的行列名稱,如果合併的矩陣都有名稱,且名稱不衝突,這些名稱會被保留:
1 | matrix1 <- matrix(1:4, nrow = 2, |
X Y
A 1 3
B 2 4
C 5 7
D 6 8
X Y Z W
A 1 3 5 7
B 2 4 6 8
但如果有名稱衝突,後面的矩陣名稱可能會覆蓋前面的:
1 | matrix3 <- matrix(5:8, nrow = 2, |
X Y
A 1 3
B 2 4
A 5 7
E 6 8
這種情況下,需要特別注意資料的正確對應。
💻 小試身手
小明是一家健身房的數據分析師,他需要對會員資料進行整理與分析。請協助他完成以下任務:
請建立三個向量記錄健身房三個分店的基本資訊:
branch_names
:分店名稱("信義店"
、"士林店"
、"中壢店"
)monthly_revenue
:各分店的月營收(單位:萬元)(120.5
、98.3
、105.7
)member_counts
:各分店的會員人數(350
、280
、310
)
請計算:
- 各分店的每位會員平均貢獻營收(月營收/會員人數)
- 三家分店的總營收與總會員數
- 哪一家分店的會員平均貢獻營收最高?(提示:使用邏輯運算)
請將三個月(1-3月)的會員資料整理成一個矩陣
member_matrix
,其中列代表不同分店,行代表不同月份的會員數,請設定適當的行名與列名,並計算每家分店的平均會員數。現在健身房又開了一家
"永和店"
,三個月的會員數分別是260
、275
、290
人。請使用rbind()
將這家新店的資料加入member_matrix
。小明想要計算各分店的會員成長率。請新增一個欄位
"成長率"
,計算方法如下,並找出哪家分店的成長率最高。
$$
\text{成長率} = \dfrac{\text{3月會員數} - \text{1月會員數}}{\text{1月會員數}} \times 100\%
$$
點我看答案
1 | # 1. 建立向量記錄健身房三個分店的基本資訊 |
信義店 士林店 中壢店
0.3442857 0.3510714 0.3409677
[1] "總營收: 324.5 萬元"
[1] "總會員數: 940 人"
[1] "會員平均貢獻營收最高的分店是: 士林店"
1月 2月 3月
信義店 330 350 365
士林店 270 280 295
中壢店 290 310 325
信義店 士林店 中壢店
348.3333 281.6667 308.3333
1月 2月 3月
信義店 330 350 365
士林店 270 280 295
中壢店 290 310 325
永和店 260 275 290
1月 2月 3月 成長率
信義店 330 350 365 10.606061
士林店 270 280 295 9.259259
中壢店 290 310 325 12.068966
永和店 260 275 290 11.538462
[1] "成長率最高的分店是: 中壢店"
矩陣運算:數學操作的向量化力量
矩陣不僅是儲存與組織資料的容器,更是進行複雜數學運算的強大工具。從最簡單的加減乘除,到進階的線性代數運算,矩陣運算在統計分析、機器學習和數據科學中都扮演著十分關鍵角色。如果有學過統計學或是計量經濟學的讀者,應該對矩陣無所不在(omnipresent)這句話不會持有懷疑 🤣 以下並不會詳細介紹矩陣運算背後的原理,如果有興趣的讀者可以參考 Spence 等人所著的 Linear Algebra 一書。
基本算術:矩陣的加減乘除
就像向量一樣,矩陣也支援基本的算術運算,但有著特定的數學規則和意義。
矩陣加法與減法
對於兩個維度相同的矩陣 $A$ 和 $B$,其中 $A = [a_{ij}]$ 和 $B = [b_{ij}]$,它們的加法定義為:
$$
C = A + B = [a_{ij} + b_{ij}]
$$
同理,減法定義為:
$$
D = A - B = [a_{ij} - b_{ij}]
$$
這意味著加法和減法是元素對應(element-wise)的操作,要求兩個矩陣的維度必須完全相同。
1 | # 建立兩個矩陣 |
[,1] [,2]
[1,] 6 10
[2,] 8 12
[,1] [,2]
[1,] -4 -4
[2,] -4 -4
矩陣的標量運算
若 $A = [a_{ij}]$ 是一個矩陣,$c$ 是一個標量(單一數值),則:
$$
cA = [c \cdot a_{ij}]
$$
代表矩陣每個元素都乘以該標量。
1 | # 矩陣乘以標量 |
[,1] [,2]
[1,] 2 6
[2,] 4 8
[,1] [,2]
[1,] 0.5 1.5
[2,] 1.0 2.0
矩陣的元素對應運算
對於兩個維度相同的矩陣 $A = [a_{ij}]$ 和 $B = [b_{ij}]$,它們的元素對應乘法,或稱為哈達瑪乘積(Hadamard product)定義為:
$$
C = A \odot B = [a_{ij} \cdot b_{ij}]
$$
元素對應除法也類似定義。
1 | # 元素對應乘法 |
[,1] [,2]
[1,] 5 21
[2,] 12 32
[,1] [,2]
[1,] 0.2000000 0.4285714
[2,] 0.3333333 0.5000000
矩陣乘法:%*%
運算子的奧秘
對於矩陣 $A$ 的維度為 $m \times n$,矩陣 $B$ 的維度為 $n \times p$,它們的矩陣乘法定義為:
$$
C = A \times B = [c_{ij}]
$$
其中
$$
c_{ij} = \sum_{k=1}^{n} a_{ik} \cdot b_{kj}
$$
簡單來說,$C$ 的第 $i$ 行第 $j$ 列的元素,等於 $A$ 的第 $i$ 行與 $B$ 的第 $j$ 列的內積。矩陣乘法要求 $A$ 的列數必須等於 $B$ 的行數。在 R 中,矩陣乘法使用 %*%
運算子,而不是 *
:
1 | # 矩陣乘法 |
[,1] [,2]
[1,] 23 31
[2,] 34 46
[,1]
[1,] 32
[,1] [,2] [,3]
[1,] 4 8 12
[2,] 5 10 15
[3,] 6 12 18
轉置、逆矩陣與其他重要變換
矩陣轉置
轉置矩陣的數學定義如下:給定一個 $m \times n$ 的矩陣 $A$,其轉置矩陣 $A^{\top}$ 是一個 $n \times m$ 的矩陣,其中 $A^{\top}$ 的元素滿足:
$$
a^{\top}_{ji} = a_{ij}
$$
對於所有的 $1 \leq i \leq m$ 和 $1 \leq j \leq n$。換句話說,轉置矩陣是透過將原矩陣的行變成列、列變成行而得到的新矩陣。例如,如果矩陣 $A$ 為:
$$
A =
\begin{bmatrix}
a_{11} & a_{12} & a_{13} \\
a_{21} & a_{22} & a_{23} \\
\end{bmatrix}
$$
則其轉置矩陣 $A^{\top}$ 為:
$$
A^{\top} =
\begin{bmatrix}
a_{11} & a_{21} \\
a_{12} & a_{22} \\
a_{13} & a_{23} \\
\end{bmatrix}
$$
在 R 語言中,可以使用 t()
函數來進行矩陣轉置操作。
1 | # 矩陣轉置 |
[,1] [,2] [,3]
[1,] 1 3 5
[2,] 2 4 6
[,1] [,2]
[1,] 1 2
[2,] 3 4
[3,] 5 6
逆矩陣
對於方陣 $A$,若存在矩陣 $A^{-1}$ 使得 $A \times A^{-1} = A^{-1} \times A = I$(其中 $I$ 是單位矩陣),則 $A^{-1}$ 稱為 $A$ 的逆矩陣(inverse matrix)。請注意,只有方陣才有逆矩陣,也就是行列的數量必須相同。
1 | # 矩陣的逆 |
[,1] [,2]
[1,] 3 2
[2,] 2 1
[,1] [,2]
[1,] -1 2
[2,] 2 -3
[,1] [,2]
[1,] 1 0
[2,] 0 1
矩陣的行列式
對於 $n \times n$ 方陣 $A$,其行列式記為 $\det(A)$ 或 $|A|$,是一個標量值,可透過多種方法計算。對於一般的 $n \times n$ 矩陣,其行列式可以通過以下方式計算:
$$
\det(A) = \sum_{\sigma \in S_n} \text{sgn}(\sigma) \prod_{i=1}^{n} a_{i,\sigma(i)}
$$
其中:
- $S_n$ 是集合 ${1, 2, \ldots, n}$ 的所有排列的集合
- $\sigma$ 是一個排列
- $\text{sgn}(\sigma)$ 是排列 $\sigma$ 的符號(+1 或 -1,取決於排列中的逆序數的奇偶性)
- $\prod_{i=1}^{n} a_{i,\sigma(i)}$ 表示乘積 $a_{1,\sigma(1)} \cdot a_{2,\sigma(2)} \cdot \ldots \cdot a_{n,\sigma(n)}$
另一種計算方法是通過展開的方法:
$$
\det(A) = \sum_{j=1}^{n} (-1)^{i+j} a_{ij} M_{ij}
$$
其中 $M_{ij}$ 是元素 $a_{ij}$ 的剩餘部分,即刪除矩陣 $A$ 的第 $i$ 行和第 $j$ 列後得到的 $(n-1) \times (n-1)$ 子矩陣的行列式。以 $2 \times 2$ 矩陣為例,其行列式較為簡單:
$$
\det\begin{pmatrix} a & b \ c & d \end{pmatrix} = ad - bc
$$
而對於 $3 \times 3$ 矩陣,行列式計算為:
$$
\det
\begin{pmatrix}
a_{11} & a_{12} & a_{13} \\
a_{21} & a_{22} & a_{23} \\
a_{31} & a_{32} & a_{33} \\
\end{pmatrix} =
a_{11}(a_{22}a_{33} - a_{23}a_{32}) - a_{12}(a_{21}a_{33} - a_{23}a_{31}) + a_{13}(a_{21}a_{32} - a_{22}a_{31})
$$
也可以表示為:
$$\det(A) = a_{11}M_{11} - a_{12}M_{12} + a_{13}M_{13}$$
其中 $M_{ij}$ 是相應的剩餘部分。
1 | # 計算行列式 |
[1] -1
小結
矩陣是 R 語言中的核心資料結構,為資料分析提供了強大的二維儲存與運算能力。透過 matrix()
函數,我們能將向量轉換為具有行列結構的矩陣,並可使用 byrow
參數控制資料填充方向。矩陣的行列命名系統(rownames()
、colnames()
、dimnames()
)讓資料更具可讀性,使用 [列,欄]
的索引系統則能精確擷取所需資料。矩陣的合併可透過 rbind()
和 cbind()
函數實現橫向與縱向擴展,但須留意維度匹配與資料型別一致性。在數學運算方面,矩陣支援加減乘除等基本算術,以及轉置、逆矩陣和行列式等進階操作,這些功能使矩陣成為統計分析、機器學習等領域不可或缺的工具。