# R 語言安裝
# 在樹莓派上安裝 R 語言
# R 語言學習筆記 (一) : 基本語法與向量
# R 語言學習筆記 (二) : 矩陣
R 語言的陣列是矩陣的維度擴展 (矩陣是陣列的一個特例, 它是二維的陣列), 因此其元素一樣也都是同質的 (即資料類型必須相同). 陣列也可視為多維度的向量 (注意, R 語言中向量並無維度), 使用多個索引如 A[i, j, k, ...] 來存取元素, 其中索引 i, j, k, ... 代表各維之位置. 最常用的是三維陣列, 在一些時間序列的應用中甚至會用到高維陣列.
與幾何類比, 向量相當於線; 矩陣相當於面; 而陣列則相當於多維空間. 不管是向量, 矩陣或陣列, 它們的元素都必須同質, 即由相同類型的資料組成.
一. 建立陣列的方法 :
1. 呼叫 array() 函數 :
函數 array() API 如下 :
array(data=NA, dim=length(data), dimnames=NULL)
data : 向量或串列 (用來填滿陣列), 向量以外的資料會自動被 as.vector() 強制轉型.
dim : 整數向量, 用來依序定義各維度之長度.
dimnames : 字串列表 (list) 用來賦予各維度因次名稱 (例如列名, 行名, 表名)
三維陣列的第一列相當於矩陣之列, 第二維相當於行, 第三維通常稱為表 (table). 例如以下的三維陣列用 1:24 的向量來填滿 3*4*2 個元素位置, 會逐行 (by column) 填入元素, 即先填滿第一行, 再填第二行 :
> A <- array(1:24, c(3,4,2)) #建立一,二,三維長度各為 3,4,2 之陣列
> A
, , 1 #顯示第三維第一個資料結構 (相當於 table 1)
[,1] [,2] [,3] [,4]
[1,] 1 4 7 10
[2,] 2 5 8 11
[3,] 3 6 9 12
, , 2 #顯示第三維第二個資料結構 (相當於 table 2)
[,1] [,2] [,3] [,4]
[1,] 13 16 19 22
[2,] 14 17 20 23
[3,] 15 18 21 24
接著來看看陣列的資料結構是用甚麼組成的 :
> class(A) #檢查資料結構是 array
[1] "array"
> is.array(A)
[1] TRUE
> is.vector(A) #不是向量結構
[1] FALSE
> is.matrix(A) #不是矩陣結構
[1] FALSE
> is.array(A[, 1 ,]) # A[ , 1, ] 是二維陣列 (降維)
[1] TRUE
> is.matrix(A[, 1, ]) # A[, 1, ] 也是矩陣 (降維)
[1] TRUE
> class(A[,1,]) # A[, 1, ] 的真實結構是矩陣
[1] "matrix"
> A[,1,]
[,1] [,2]
[1,] 1 13
[2,] 2 14
[3,] 3 15
> A[1,1,]
[1] 1 13
> is.matrix(A[1,1,]) #A[1, 1, ] 則降維成向量
[1] FALSE
> is.vector(A[1,1,])
[1] TRUE
上面降維後的 A[ , 1, ] 用 is.array() 與 is.matrix() 檢查, 結果它似乎既是陣列 (二維) 也是矩陣, 用 class() 去檢驗即知事實上 A[ , 1, ] 結構是矩陣而非陣列, 可見陣列確實是用矩陣堆起來的, 而矩陣又是用向量堆起來的.
其實 R 語言中的二維陣列就是矩陣, 例如用 array() 建立一個二維陣列, 用 is.array() 與 is.matrix() 都回應 TRUE, 表示它既是陣列也是矩陣, 但用 class() 去檢查其結構類型卻歸類為是矩陣 :
> A <- array(1:12, c(4,3)) #建立一個二維陣列
> A
[,1] [,2] [,3]
[1,] 1 5 9
[2,] 2 6 10
[3,] 3 7 11
[4,] 4 8 12
> is.array(A) #用 array() 建立當然是陣列
[1] TRUE
> is.matrix(A) #也是矩陣
[1] TRUE
> class(A) #結構上歸類為矩陣
[1] "matrix"
> A <- matrix(1:12, nrow=4) #建立一個矩陣
> A
[,1] [,2] [,3]
[1,] 1 5 9
[2,] 2 6 10
[3,] 3 7 11
[4,] 4 8 12
> is.matrix(A) #用 matrix() 建立當然是矩陣
[1] TRUE
> is.array(A) #嘿! A 竟然也是陣列
[1] TRUE
> class(A) #結構是矩陣
[1] "matrix"
> B <- as.array(A) #用 as.array() 將 A 強制轉型為陣列 B
> B
[,1] [,2] [,3]
[1,] 1 5 9
[2,] 2 6 10
[3,] 3 7 11
[4,] 4 8 12
> is.matrix(B) #還是矩陣
[1] TRUE
> is.array(B) #當然是陣列
[1] TRUE
> class(B) #結構仍歸類為矩陣
[1] "matrix"
我們可以用 identical() 函數來檢驗用 matrix() 與 array() 建立的二維物件是否雷同 :
> A <- matrix(1:12, nrow=4) #建立一個矩陣 A
> A
[,1] [,2] [,3]
[1,] 1 5 9
[2,] 2 6 10
[3,] 3 7 11
[4,] 4 8 12
> B <- array(1:12, c(4,3)) #建立一個二維陣列 B, 內容與 A 矩陣相同
> B
[,1] [,2] [,3]
[1,] 1 5 9
[2,] 2 6 10
[3,] 3 7 11
[4,] 4 8 12
> class(A) #矩陣 A 結構為 matrix
[1] "matrix"
> class(B) #陣列 B 結構亦為 matrix
[1] "matrix"
> identical(A, B) #呼叫 identical() 顯示兩者是同樣物件
[1] TRUE
總之, 在 R 語言中, 大於二維的資料結構是陣列, 二維陣列就被歸類為矩陣.
如果傳入的向量不夠填滿陣列, 則會套用循環規則從頭抓資料, 例如 :
> array(1:17, c(3,4,2))
, , 1
[,1] [,2] [,3] [,4]
[1,] 1 4 7 10
[2,] 2 5 8 11
[3,] 3 6 9 12
, , 2
[,1] [,2] [,3] [,4]
[1,] 13 16 2 5
[2,] 14 17 3 6
[3,] 15 1 4 7
> A <- array(1:24, c(3,2,2,2))
> A
, , 1, 1
[,1] [,2]
[1,] 1 4
[2,] 2 5
[3,] 3 6
, , 2, 1
[,1] [,2]
[1,] 7 10
[2,] 8 11
[3,] 9 12
, , 1, 2
[,1] [,2]
[1,] 13 16
[2,] 14 17
[3,] 15 18
, , 2, 2
[,1] [,2]
[1,] 19 22
[2,] 20 23
[3,] 21 24
五維陣列範例如下 :
> A <- array(1:32, c(2,2,2,2,2))
> A
, , 1, 1, 1
[,1] [,2]
[1,] 1 3
[2,] 2 4
, , 2, 1, 1
[,1] [,2]
[1,] 5 7
[2,] 6 8
, , 1, 2, 1
[,1] [,2]
[1,] 9 11
[2,] 10 12
, , 2, 2, 1
[,1] [,2]
[1,] 13 15
[2,] 14 16
, , 1, 1, 2
[,1] [,2]
[1,] 17 19
[2,] 18 20
, , 2, 1, 2
[,1] [,2]
[1,] 21 23
[2,] 22 24
, , 1, 2, 2
[,1] [,2]
[1,] 25 27
[2,] 26 28
, , 2, 2, 2
[,1] [,2]
[1,] 29 31
[2,] 30 32
可見 R 語言在顯示高維陣列內容時, 是把它拆解到矩陣 (就是第一與第二維組成的二維陣列) 當作最小的單位, 然後從第三維起依序顯示 "每一張表".
2. 呼叫 dim() 函數設定維度將向量或列表變成陣列 :
R 語言中向量 (vector) 是一群有序資料, 看起來像是一維, 但在 R 裡面是沒有維度的資料結構, 用 dim() 檢查會得到 NULL. 與建立矩陣一樣, 若呼叫 dim() 為向量指定大於 2 的維度, 則此無維度的向量將變成有維度的陣列結構, 例如 :
> v <- 1:24 #建立 24 個元素的向量
> dim(v) #向量是無維度的資料結構 (NULL)
NULL
> dim(v) <- c(4,3,2) #指定維度給向量會使其變成矩陣 (2 維) 或向量 (大於 2 維)
> v
, , 1
[,1] [,2] [,3]
[1,] 1 5 9
[2,] 2 6 10
[3,] 3 7 11
[4,] 4 8 12
, , 2
[,1] [,2] [,3]
[1,] 13 17 21
[2,] 14 18 22
[3,] 15 19 23
[4,] 16 20 24
> class(v) #變成陣列了
[1] "array"
> dim(v) #查詢陣列維度是 4*3*2
[1] 4 3 2
二. 存取陣列元素 :
存取陣列元素的方式與矩陣一樣, 也是用索引, 只是索引比較多而已.
> A <- array(1:24, c(4,3,2))
> A
, , 1
[,1] [,2] [,3]
[1,] 1 5 9
[2,] 2 6 10
[3,] 3 7 11
[4,] 4 8 12
, , 2
[,1] [,2] [,3]
[1,] 13 17 21
[2,] 14 18 22
[3,] 15 19 23
[4,] 16 20 24
> A[1,1,1]
[1] 1
> A[1,3,1]
[1] 9
> A[1,3,2]
[1] 21
> A[1,1,]
[1] 1 13
> A[1,,]
[,1] [,2]
[1,] 1 13
[2,] 5 17
[3,] 9 21
> A[,1,]
[,1] [,2]
[1,] 1 13
[2,] 2 14
[3,] 3 15
[4,] 4 16
> A[,,1]
[,1] [,2] [,3]
[1,] 1 5 9
[2,] 2 6 10
[3,] 3 7 11
[4,] 4 8 12
注意, 這些取出來的物件都降階變成了二維的矩陣了, 可用 class() 檢驗. 如果取出來的元件想保留 array 架構, 不要降階成矩陣, 可以在索引最後面加上 drop=FALSE (預設是 TRUE), 例如 :
> A <- array(1:24, c(4,3,2))
> A[1,,] #只取第一維
[,1] [,2]
[1,] 1 13
[2,] 5 17
[3,] 9 21
> class(A[1,,]) #降階為 matrix
[1] "matrix"
> A[1,,,drop=FALSE] #不降階 (保留陣列結構)
, , 1
[,1] [,2] [,3]
[1,] 1 5 9
, , 2
[,1] [,2] [,3]
[1,] 13 17 21
> class(A[1,,,drop=FALSE]) #仍為 array 結構
[1] "array"
> identical(A[1,,], A[1,,,drop=FALSE]) #兩個是不同物件 (內容相同, 但結構不同)
[1] FALSE
上面是存取三維陣列內容時的降維情形, 如果取得的內容是二維, 則降階為矩陣; 若小於二維則為向量. 從多維陣列取得的內容如果大於二維, 則仍然是陣列結構, 例如 :
> A <- array(1:32, c(2,2,2,2,2))
> A
, , 1, 1, 1
[,1] [,2]
[1,] 1 3
[2,] 2 4
, , 2, 1, 1
[,1] [,2]
[1,] 5 7
[2,] 6 8
, , 1, 2, 1
[,1] [,2]
[1,] 9 11
[2,] 10 12
, , 2, 2, 1
[,1] [,2]
[1,] 13 15
[2,] 14 16
, , 1, 1, 2
[,1] [,2]
[1,] 17 19
[2,] 18 20
, , 2, 1, 2
[,1] [,2]
[1,] 21 23
[2,] 22 24
, , 1, 2, 2
[,1] [,2]
[1,] 25 27
[2,] 26 28
, , 2, 2, 2
[,1] [,2]
[1,] 29 31
[2,] 30 32
> A[,,,1,1] #取得子陣列
, , 1
[,1] [,2]
[1,] 1 3
[2,] 2 4
, , 2
[,1] [,2]
[1,] 5 7
[2,] 6 8
> class(A[,,,1,1]) #結構是陣列 (因為是三維)
[1] "array"
取得陣列內容時也可以使用負索引來排除不要的部分, 例如 :
> A <- array(1:24, c(4,3,2))
> A
, , 1
[,1] [,2] [,3]
[1,] 1 5 9
[2,] 2 6 10
[3,] 3 7 11
[4,] 4 8 12
, , 2
[,1] [,2] [,3]
[1,] 13 17 21
[2,] 14 18 22
[3,] 15 19 23
[4,] 16 20 24
> A[-3, c(1,3), 2] #第一維不要第三列, 第二維取第一與第三行, 第三維取第二張
[,1] [,2]
[1,] 13 21
[2,] 14 22
[3,] 16 24
修改陣列的內容只要直接將向量或矩陣指派給陣列的指定部分即可, 例如 :
> A <- array(1:24, c(4,3,2)) #建立陣列
> A
, , 1
[,1] [,2] [,3]
[1,] 1 5 9
[2,] 2 6 10
[3,] 3 7 11
[4,] 4 8 12
, , 2
[,1] [,2] [,3]
[1,] 13 17 21
[2,] 14 18 22
[3,] 15 19 23
[4,] 16 20 24
[,1] [,2]
[1,] 3 11
[2,] 4 12
> A[3:4,c(1,3),1] <- matrix(NA, nrow=2, ncol=2) #將矩陣指派給陣列局部
> A
, , 1
[,1] [,2] [,3]
[1,] 1 5 9
[2,] 2 6 10
[3,] NA 7 NA
[4,] NA 8 NA
, , 2
[,1] [,2] [,3]
[1,] 13 17 21
[2,] 14 18 22
[3,] 15 19 23
[4,] 16 20 24
三. 陣列常用函數 :
函數 | 說明 |
array(data, dim, dimnames) | 建立維度為 dim 向量之陣列 |
str(x) | 顯示物件結構與內容 |
length(x) | 顯示陣列元素個數 |
dim(x) | 顯示物件 (矩陣, 陣列, 資料框) 維度 |
is.array(x) | 檢查是否為鎮ㄌㄧ類型 |
as.array(x) | 將物件強制轉型為陣列陣類型 |
identical(x, y) | 檢查兩個物件 x, y 是否為相同物件 |
沒有留言:
張貼留言