重複向量
在處理向量的運算時,如果遇到長度不同的向量,R 就會將長度較短的向量自動重複,直到其長度跟最長的向量相同為止,例如:
1:3 + 1:9
[1] 2 4 6 5 7 9 8 10 12
這裡的 1:3
向量長度為 3,而 1:9
向量長度為 9,所以 R 會將 1:3
重複 3 次,變成 c(1, 2, 3, 1, 2, 3, 1, 2, 3)
之後,再跟 1:9
進行運算。
當遇到向量與常數相加時,也是依據同樣的規則處理:
1:5 + 1
[1] 2 3 4 5 6
這裡的 1
在 R 中其實是一個長度為 1 的向量,而為了要跟 1:5
這個長度為 5 的向量進行運算,R 會將 1
自動重複 5 次,變成 c(1, 1, 1, 1, 1)
之後再進行運算。
如果遇到最長向量長度不是較短向量長度的整數倍時,最後一次的向量重複內容就會不完整(超過的部分會捨去),並且也會產生警告訊息:
1:2 + 1:5
[1] 2 4 4 6 6 Warning message: In 1:2 + 1:5 : 較長的物件長度並非較短物件長度的倍數
以這個例子來說,1:2
會重複 2.5 次,變成 c(1, 2, 1, 2, 1)
之外再進行運算。
如果要產生重複性的向量,可以使用 rep
這個函數,其第一個參數是要重複的向量,而第二個參數則是重複次數:
rep(1:4, 3)
[1] 1 2 3 4 1 2 3 4 1 2 3 4
如果要讓每一個元素個別重複之後再串接起來,可以使用 each
參數:
rep(1:4, each = 3)
[1] 1 1 1 2 2 2 3 3 3 4 4 4
也可以透過向量的方式指定重複次數,讓每一個元素重複不同的次數:
rep(1:4, 4:1)
[1] 1 1 1 1 2 2 2 3 3 4
另外也可以直接指定輸出的向量長度,讓 rep
自動計算重複的次數:
rep(1:4, length.out = 7)
[1] 1 2 3 4 1 2 3
rep.int
是一個執行效率較高的版本,大部分的狀況下可以代替 rep
:
rep.int(1:4, 3)
[1] 1 2 3 4 1 2 3 4 1 2 3 4
rep_len
是另一個高執行效率的版本:
rep_len(1:4, 7)
[1] 1 2 3 4 1 2 3
矩陣與陣列
R 中的向量(vectors)是用來儲存一維資料的變數類型,而如果需要儲存二維以上的資料,就要使用陣列(arrays)來處理,而二維的陣列就是我們所熟知的矩陣(matrices)。
建立矩陣與陣列
R 的矩陣可以使用 matrix
函數建立,例如:
matrix(1:6, nrow = 2, ncol = 3)
這樣就會建立一個 2 x 3 的矩陣:
[,1] [,2] [,3] [1,] 1 3 5 [2,] 2 4 6
byrow
參數可以調整資料排列的方向:
matrix(1:6, nrow = 2, ncol = 3, byrow = TRUE)
[,1] [,2] [,3] [1,] 1 2 3 [2,] 4 5 6
矩陣的行與列可以使用 dimnames
參數指定名稱:
matrix(1:6, nrow = 2, ncol = 3, dimnames = list(c("row1", "row2"), c("C.1", "C.2", "C.3")))
C.1 C.2 C.3 row1 1 3 5 row2 2 4 6
多維度的陣列則是使用 array
函數來建立:
array(1:24, dim = c(4, 3, 2))
, , 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
多維度的陣列也可以使用 dimnames
參數指定每個維度的資料名稱:
array(1:24, dim = c(4, 3, 2), dimnames = list( X = c("A1","A2","A3","A4"), Y = c("B1", "B2", "B3"), Z = c("C1", "C2")))
, , Z = C1 Y X B1 B2 B3 A1 1 5 9 A2 2 6 10 A3 3 7 11 A4 4 8 12 , , Z = C2 Y X B1 B2 B3 A1 13 17 21 A2 14 18 22 A3 15 19 23 A4 16 20 24
事實上二維的陣列就是矩陣,不管使用 matrix
或是 array
來產生,結果都是一樣的:
x.matrix <- matrix(1:6, nrow = 2, ncol = 3) x.array <- array(1:6, dim = c(2, 3)) identical(x.matrix, x.array)
[1] TRUE
如果我們檢查 x.array
的類型,會發現它實際上就是一個矩陣變數:
class(x.array)
[1] "matrix"
nrow
與 ncol
函數可以檢查矩陣的列數與行數:
nrow(x.matrix)
[1] 2
ncol(x.matrix)
[1] 3
nrow
與 ncol
函數若用於多維度的陣列,會傳回前兩個維度的長度。
x.array <- array(1:60, dim = c(3, 4, 5)) nrow(x.array)
[1] 3
ncol(x.array)
[1] 4
length
函數也可以用於矩陣或是陣列,他會計算矩陣或陣列中所有元素的個數(也就是所有維度長度的乘積):
length(x.matrix)
[1] 6
length(x.array)
[1] 60
若要改變矩陣或陣列的維度,可以使用 dim
指定新的維度:
x.matrix <- matrix(1:12, nrow = 4, ncol = 3) dim(x.matrix) <- c(2, 6) x.matrix
[,1] [,2] [,3] [,4] [,5] [,6] [1,] 1 3 5 7 9 11 [2,] 2 4 6 8 10 12
甚至可以透過改變維度,將二維矩陣轉換為高維度的陣列:
dim(x.matrix) <- c(2, 3, 2) x.matrix
, , 1 [,1] [,2] [,3] [1,] 1 3 5 [2,] 2 4 6 , , 2 [,1] [,2] [,3] [1,] 7 9 11 [2,] 8 10 12
nrow
、ncol
與 dim
這幾個函數如果用在一維的向量時,會傳回 NULL
,如果想要避免這個問題,可以改用 NROW
與 NCOL
函數,這兩個函數的作用跟 nrow
與 ncol
相同,但是當遇到一維的向量時也可以傳回有意義的值:
x.vector <- 1:5 nrow(x.vector)
NULL
NROW(x.vector)
[1] 5
ncol(x.vector)
NULL
NCOL(x.vector)
[1] 1