迷你課程:R語言-3~list, matrix與array的子集提取

Quick look
今天介紹R中如何對 List、Matrix和Array(陣列)進行子集提取(Subsetting)的操作,包含:
- 列表的多種提取方式。
- 矩陣基本子集提取方法。
- 陣列的多維子集提取技巧。
List的子集提取
先建立一個list
my_list <- list(
Name = "Yang-Hong",
Age = 35,
Scores = c(85.5, 90.2, 78.9),
Matrix = matrix(1:9, nrow = 3)
)
#>
$Name
[1] "Yang-Hong"
$Age
[1] 35
$Scores
[1] 85.5 90.2 78.9
$Matrix
[,1] [,2] [,3]
[1,] 1 4 7
[2,] 2 5 8
[3,] 3 6 9
提取list的元素:
# 使用名稱提取
my_list$Name # "Yang-Hong"
# 使用雙中括號提取
my_list[["Age"]] # 35
# 使用數字索引
my_list[[3]] # [85.5 90.2 78.9]
注意上面數字索引的部分需要用[[]]
才能完整將元素取出,如果只用[]
也可以取出來物件,但是會帶有list的結構。
同理名稱索引也會有一樣的情況。
提取子列表
但若是要提取一個子列表,就可以用數字加上[]
:
# 提取一個子列表,提取第一個與第二個元素,返回結構仍是一個list
sub_list <- my_list[1:2]
鑲嵌提取
如果列表中的元素是更複雜的數據結構,可以進行鑲嵌提取:
# 提取 Matrix 中的第一列
my_list$Matrix[1, ] # [1 4 7]
另外要注意的是,
$
支援partial matching,但[[]]
不行,因此用[[]]
會比較不會出錯。
Matrix的子集提取
矩陣是一個2維數據結構,僅允許存儲相同類型的數據。可以通過行和列進行子集提取。 先建立一個matrix:
# 建立一個 3x3 的矩陣
mat <- matrix(
data = 1:9,
nrow = 3, #根據data長度來調整行與列的數量
ncol = 3,
byrow = TRUE #決定依循row方向排列與否。
)
#>
[,1] [,2] [,3]
[1,] 1 2 3
[2,] 4 5 6
[3,] 7 8 9
提取單個元素
# 提取第一行第一列的元素
mat[1, 1] # [1]
提取整行或整列
# 提取第二列
mat[2, ] # [4 5 6]
# 提取第三行
mat[, 3] # [3 6 9]
提取子矩陣
# 提取第一到第二行,第二到第三列的子矩陣
sub_mat <- mat[1:2, 2:3]
得到:
#>
[2 3]
[5 6]
保持matrix結構
一般直接取出matrix的整列或整行會得到atomic vector
,但若要維持matrix的結構,可以加上參數drop=FALSE
:
mat[, 3, drop=FALSE]
得到:
#>
[,1]
[1,] 3
[2,] 6
[3,] 9
邏輯條件提取
可以使用邏輯條件
篩選矩陣中的特定元素:
# 找出矩陣中大於5的元素
mat[mat > 5] # [7 8 6 9]
# 設定條件篩選
selected <- mat[mat %% 2 == 0] # 提取偶數
搭配which()
使用which()
可以得到符合邏輯條件的元素位置在哪。
which(mat>5)
#>
[1] 3 6 8 9 #表示在這些位置元素的值>5
上面的位置是順著column來數,所以第三個位置落在第一行第三列,數值為7且大於5,第8個位置落在第三行第二列,數值為6且大於5。
我們也可以再用這些返回的位置將數值取出來:
mat[which(mat>5)]
#>
[1] 7 8 6 9
然而如果希望取出來的位置或index可以給我們行列的配對,在使用which()的時候可以加上arr.ind=TRUE
which(mat>5, arr.ind=TRUE)
會得到確切的行列位置:
#>
row col
[1,] 3 1
[2,] 3 2
[3,] 2 3
[4,] 3 3
而這個返回的數據為matrix的結構,而matrix可以當成索引的條件來找出矩陣裡面相對應的元素。
同樣的道理,如果今天有兩個索引向量一個代表row,一個代表column,用
cbind()
結合起來的結構也是matrix,也可以丟回去來索引matrix中某row某column的數值。這個在分析基因序列建立矩陣時可能會用到,當成one-hot encoding的方式之一。
Array的子集提取
陣列是R中的多維數據結構,可以具有多於兩個維度。子集提取時可以按多維索引操作。
建立array
# 建立一個3x3x2的三維陣列
arr <- array(
data = 1:18,
dim = c(3, 3, 2) #代表有兩層,每一層維度=3x3
)
#>
第一層:
[,1] [,2] [,3]
[1,] 1 4 7
[2,] 2 5 8
[3,] 3 6 9
第二層:
[,1] [,2] [,3]
[1,] 10 13 16
[2,] 11 14 17
[3,] 12 15 18
提取單個元素
# 提取第一層第一行第二列的元素
arr[1, 2, 1] # [4]
提取整列或整行
# 提取第二層的第三行
arr[, 3, 2] # [16 17 18]
# 提取第一層的第二列
arr[2, , 1] # [2 5 8]
提取特定切片
# 提取第一層的所有數據
slice <- arr[, , 1]
邏輯條件提取
array也可以進行邏輯條件選取。
# 找出所有大於10的元素
arr[arr > 10] # [11 12 13 14 15 16 17 18]
# 選擇特定條件的子陣列
selected <- arr[arr %% 3 == 0]
課程小結
資料結構 | 特性 | 提取範例 |
---|---|---|
List | 可儲存不同型態數據,靈活提取多層結構 | my_list[["Name"]] |
Matrix | 二維結構,行列提取 | mat[1, 2] |
Array | 多維結構,支援多層提取 | arr[1, 2, 3] |